после вызова closesocket heap освобождается лишь частично

Тема в разделе "WASM.BEGINNERS", создана пользователем wasmer, 4 июн 2008.

  1. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    при вызове функции socket выделяется память в heap функцией ntdll!RtlAllocateHeap, а при вызове closesocket она освобождается
    однако у меня в программе освобождается лишь часть выделенной памяти. С чем это может быть связано?
     
  2. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Возможно с кривизной ws2_32.dll. У меня, к примеру, проги вылетают (правда только из под отладчика) на функции listen.
     
  3. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    какая может быть кривизна в XP SP2?
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    wasmer
    Если смотришь по общему объему памяти, занимаемой процессом, то это нормальное явление.
    Во-первых, менеджер кучи сам решает сколько и когда ему брать страниц памяти у системы и сколько и когда отдавать. Если HeapAlloc\RtlAllocateHeap выделяют доп.страницы памяти в конце кучи под выделяемый блок памяти, то после его освобождения HeapFree выделенные страницы не обязательно отдаются назад системе, поскольку 1) менеджер сохраняет некоторый запас переданных страниц в конце кучи (чтобы лишний раз не дергать VirtualAlloc), 2) выделенный блок может оказаться "зажатым" другим блоком, выделенным после него - в этом случае освобождаемый блок просто помечается свободным и при этом память, выделенная процессу вообще не уменьшается, т.к. освобождаться могут только страницы памяти, расположенные в конце кучи.
    Во-вторых, при вызовах некоторых функций системой могут создаваться служебные структуры данных, которые сохраняются для дальнейше работы. Например, при первом вызове GlobalAlloc с флагом GMEM_MOVEABLE менеджер кучи выделяет память под таблицу дескрипторов hGlobal, которая так и остается висеть в памяти даже после освобождения всех hGlobal. Это же может относиться и ко всем прочим хэндлам (в т.ч. видимо и к сокетам).
    Плюс куча прочих "фишек". Например, память под стек может только увеличиваться (в результате выделения больших локальных массивов данных, рекурсивных вызовов функций или обработки исключений). При вызове GetClipboardData данные зависают в куче до следующего вызова OpenClipboard. И т.д. и т.п. Поэтому судить об "утечках памяти" по общему объему памяти, занимаемой процессом нельзя. Нужно следить за собой, за своими собственными выделениями\освобождениями памяти и не лезть в вотчину винды :)
     
  5. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    я слежу за количеством свободной памяти в WinDbg командой

    dt _heap TotalFreeSize 140000

    140000 - адрес default heap моего процесса
    после вызова функции socket TotalFreeSize уменьшается, после closesocket TotalFreeSize увеличивается, но не на столько насколько она уменьшилась
    почему это происходит? может ли это быть признаком heap corruption?
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    wasmer
    Нравится дос ? :)
     
  7. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    а причём здесь дос?
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    При том > я слежу за количеством свободной памяти в WinDbg командой
    Этоже не ядерное приложение, для отладки юзермодных приложений использовать WinDbg - это как без эксплорера, а в консоле работать.
     
  9. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    вы не правы, WinDbg используется как для отладки системных, так и пользовательских приложений
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Та знаю я, я о том что это слишком неудобно.
     
  11. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    для меня он как раз удобней чем OllyDbg и SoftIce
     
  12. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    нашёл место, где выделяется память, которая потом не освобождается
    вот callstack:

    kernel32!GlobalAlloc
    WS2HELP!WahInsertHandleContext+0x15b
    mswsock!WSPSocket+0x5ca
    WS2_32!WSASocketW+0xce
    WS2_32!socket+0x73

    функция GlobalAlloc вызывается из функции WahInsertHandleContext не всегда при создании сокета, а только иногда, причём два раза, и выделяет она всё время по 0x80 байт
    эти 0x100 байт и не освобождаются при вызове closesocket функцией RtlFreeHeap

    вот кажется статья об этом
    http://support.microsoft.com/kb/322980
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    wasmer
    Молодец, глубоко копаешь ;)
    PS: см.пост #4 "Во-вторых, ..."
     
  14. wasmer

    wasmer New Member

    Публикаций:
    0
    Регистрация:
    19 янв 2007
    Сообщения:
    104
    да, leo, вы были правы - система сама создаёт таблицу Handle-To-Pointer Translation Table и не освобождает память пока не будет вызвана функция WSACleanup