1. Присоединяйтесь к нашему дискорд серверу: https://discord.gg/gGtcVT9CKs
    У проекта OZ Game есть свой собственный PvPGN сервер для игры в Warcraft 3!
    На данном сервере вы найдёте все наши хосты.

Недостаточно памяти для обработки команды

Тема в разделе "Новости портала", создана пользователем OZ.Robert, 2 окт 2023.

  1. TopicStarter Overlay
    OZ.Robert

    OZ.Robert Chief Moderator Команда форума Супер Модератор Premium

    Сообщения:
    5.558
    Симпатии:
    4.225
    Когда у игры неполучается выделить память, она показывает сообщение об ошибке "Недостаточно памяти для обработки команды".
    Произойти это может, если память доступная процессу игры кончилась.
    Даже если у вас 64-битный процессор и десятки гигабайт оперативной памяти, игра 32-битная и не может использовать больше 4-ех гигабайт памяти.
    А на практике, даже больше 2-ух гигабайт будет проблемно занять, из-за особенности устройства используемых варкрафтом связных списков.

    Регионы памяти:
    В конце отчета об ошибке, создаваемого игрой при краше от нехватки памяти, можно увидеть таблицу регионов памяти.
    12 2784 e:\Drive1\temp\buildwar3x\War3\Source\UI/CCommandButton.cpp(546)
    1 528 .\FrameDef.cpp(69)
    12 768 e:\drive1\temp\buildwar3x\war3\source\game\CFogMaskTable.h(98)
    1 56 .\CGameUI.cpp(517)
    1 512 e:\Drive1\temp\buildwar3x\War3\Source\WorldEdit/WEUtilities.cpp(3422)
    286 12308 .\W32\OsISndCache.cpp(991)
    143 4004 .?AUNATIVETOKEN@@(-2)
    ...
    Первая колонка содержит количество выделенных блоков памяти, а вторая их сумарный размер.Дальше идет либо имя исходного файла и номер строки, либо закодированое имя типа и отрицательное число.
    По моим наблюдениям, выделение памяти может также провалиться в случае, когда размер одного региона менеджера памяти достигает лимита, равного примерно 256-ми мегабайтам.Так что, даже если память еще не закончилась, но блоков памяти в одном регионе выделено слишком много, то игра всё равно может крашнуться. Также, могу предположить, что если игра попытается одним куском выделить много памяти (например, 300 МБ), то последствия будут теми же.
    По сигнатуре региона можно попытаться догадаться о причине произошедшего.Например, если имя объекта CUnitListNode, то можно заподозрить утечки памяти, связанные с неудаляемыми групами в скрипте карты.

    Читаемая таблица регионов
    Для более удобного просмотра таблицы, предлагаю воспользоваться моим скриптом на питоне, который сортирует элементы таблицы и конвертирует их в более читаемый вид.Установите python последнией версии (3.x), но может быть и на старых заработает
    import sys
    import re
    from contextlib import nullcontext
    from collections import namedtuple


    def open_input(path):
    return open(path, 'rt') if path != '-' else nullcontext(sys.stdin)


    def open_output(path):
    return open(path, 'wt') if path != '-' else nullcontext(sys.stdout)


    input_path = sys.argv[1]
    output_path = sys.argv[2]


    with open_input(input_path) as f:
    input_data = f.readlines()


    pattern = re.compile(r' *([0-9]+) +([0-9]+) +(.*)\((-?[0-9]+)\)')


    MemoryRegion = namedtuple('MemoryRegion', ['blocks_count', 'size', 'source_file', 'source_line'])


    def parse_line(line):
    m = pattern.match(line)
    if m:
    return MemoryRegion(
    blocks_count = int(m.group(1)),
    size = int(m.group(2)),
    source_file = m.group(3),
    source_line = int(m.group(4)),
    )


    def parse_lines(lines):
    for i, line in enumerate(lines):
    parsed_line = parse_line(line)
    if parsed_line:
    yield parsed_line
    else:
    raise Exception(f'Failed to convert line number {i+1}.')

    memory_regions = list(parse_lines(input_data))
    total_size = sum(r.size for r in memory_regions)
    sorted_memory_regions = sorted(memory_regions, reverse=True, key=lambda r: r.size)
    formatted_memory_regions = (format_memory_region(r) for r in sorted_memory_regions)


    def format_size(size):
    suffixes = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB']


    i = 0
    while size >= 1024:
    size /= 1024
    i += 1


    if i >= len(suffixes):
    i = len(suffixes) - 1


    if i > 0:
    return f'{size:.2f} {suffixes}'
    else:
    return f'{size} {suffixes}'


    def format_memory_region(r):
    pretty_size = format_size(r.size)
    return f'{pretty_size}\t{r.blocks_count}\t{r.source_file}\t{r.source_line}'


    with open_output(output_path) as f:
    f.write(f'total size: {format_size(total_size)}.\n')
    f.write('\n'.join(formatted_memory_regions))
    f.write('\n')

    ВНИМАНИЕ!

    python wc3memsort.py <путь к файлу с исходной таблицей> <путь к файлу для записи результата>


    Вместо пути может быть указан минус "-", в таком случае для чтения или записи будет использоваться стандартный ввод/вывод.
    На вход скрипт принимает не весь отчет об ошибке, а лишь фрагмент с таблицей находящийся в конце файла между разделяющими полосами.
    На выходе пишется сначала сумарное количество памяти, занимаемое всеми регионами памяти, а затем таблица регионов, в которой первая колонка содержит размер региона памяти, а вторая количество блоков памяти. Дальше, как и в оригинале, идет сигнатура региона.

    [FONT=Trebuchet MS, Helvetica, Arial, sans-serif]

    total size: 670.44 MiB.
    145.41 MiB 1584 .?AVCAgentBaseAbs@@ -2
    62.51 MiB 95047 .\cmemblock.cpp 372
    59.05 MiB 40199 .?AVC3Vector@NTempest@@ -2
    51.49 MiB 1468 .?AUCustomObjectField@@ -2
    51.28 MiB 729588 .\CDataAllocator.cpp 152
    ...

     
    LTDZadrottt и trush11 нравится это.

Похожие темы
  1. OZ.Robert
    Ответов:
    37
    Просмотров:
    1.678
Загрузка...