FreeLibrary() не полностью освобождает память?

Тема в разделе "WASM.BEGINNERS", создана пользователем _sheva740, 15 апр 2011.

  1. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Приложение по LoadLibrary() подгружает dll - ки,
    работает допустим с ними. Потом по FreeLibrary()
    выгружает их.

    Остается неосвобожденной (как по мне) некоторый объем памяти?

    Вот тестовый пример:
    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\kernel32.inc
    7. include \masm32\include\user32.inc
    8. include \masm32\include\masm32.inc
    9.  
    10. includelib \masm32\lib\user32.lib
    11. includelib \masm32\lib\kernel32.lib
    12. includelib \masm32\lib\masm32.lib
    13.  
    14. include \masm32\include\psapi.inc
    15. includelib \masm32\lib\psapi.lib
    16.  
    17. .data
    18.     PROCESS_MEMORY_COUNTERS STRUCT
    19.         cb                          DWORD ?
    20.         PageFaultCount              DWORD ?
    21.         PeakWorkingSetSize          DWORD ?
    22.         WorkingSetSize              DWORD ?
    23.         QuotaPeakPagedPoolUsage     DWORD ?
    24.         QuotaPagedPoolUsage         DWORD ?
    25.         QuotaPeakNonPagedPoolUsage  DWORD ?
    26.         QuotaNonPagedPoolUsage      DWORD ?
    27.         PagefileUsage               DWORD ?
    28.         PeakPagefileUsage           DWORD ?
    29.     PROCESS_MEMORY_COUNTERS ENDS
    30.  
    31.     pmc PROCESS_MEMORY_COUNTERS  <>
    32.  
    33.     szlib00     db 'lib00.dll',0
    34.     szlib01     db 'lib01.dll',0
    35.     szlib02     db 'lib02.dll',0
    36.  
    37.     hlib00      dd 0
    38.     hlib01      dd 0
    39.     hlib02      dd 0
    40.     hProcess        dd 0
    41.  
    42.     template        db "   Loading Plugin : %s",13,10,0
    43.     template1       db "   UnLoading Plugin : %s",13,10,0
    44.     template2       db "   Process use : %d   byte",13,10,0
    45.     TextBuf     db 100 dup( ? )
    46.  
    47.     input_buffer    db 2 dup(0)
    48.  
    49.     lf      db 13,10,0
    50.  
    51. .code
    52. main:
    53. ;*******************************************************************
    54.     invoke  GetCurrentProcess
    55.     mov hProcess, eax
    56.  
    57.     invoke  StdOut,addr lf
    58.     invoke  GetProcessMemoryInfo, hProcess, ADDR pmc, SIZEOF pmc
    59.     mov eax, pmc.WorkingSetSize
    60.     invoke  wsprintf,addr TextBuf,addr template2,eax
    61.     invoke  StdOut,addr TextBuf
    62.     invoke  StdOut,addr lf
    63.  
    64.     invoke  LoadLibrary,addr szlib00
    65.     mov hlib00,eax
    66.  
    67.     invoke  wsprintf,addr TextBuf,addr template,addr szlib00
    68.     invoke  StdOut,addr TextBuf
    69.  
    70.     invoke  LoadLibrary,addr szlib01
    71.     mov hlib01,eax
    72.  
    73.     invoke  wsprintf,addr TextBuf,addr template,addr szlib01
    74.     invoke  StdOut,addr TextBuf
    75.  
    76.     invoke  LoadLibrary,addr szlib02
    77.     mov hlib02,eax
    78.  
    79.     invoke  wsprintf,addr TextBuf,addr template,addr szlib02
    80.     invoke  StdOut,addr TextBuf
    81.  
    82.     invoke  StdOut,addr lf
    83.     invoke  GetProcessMemoryInfo, hProcess, ADDR pmc, SIZEOF pmc
    84.     mov eax, pmc.WorkingSetSize
    85.     invoke  wsprintf,addr TextBuf,addr template2,eax
    86.     invoke  StdOut,addr TextBuf
    87.     invoke  StdOut,addr lf
    88.  
    89.  
    90.     invoke  Sleep, 1000
    91.  
    92.  
    93.     invoke  FreeLibrary,hlib02
    94.     invoke  wsprintf,addr TextBuf,addr template1,addr szlib02
    95.     invoke  StdOut,addr TextBuf
    96.  
    97.     invoke  FreeLibrary,hlib01
    98.     invoke  wsprintf,addr TextBuf,addr template1,addr szlib01
    99.     invoke  StdOut,addr TextBuf
    100.  
    101.     invoke  FreeLibrary,hlib00
    102.     invoke  wsprintf,addr TextBuf,addr template1,addr szlib00
    103.     invoke  StdOut,addr TextBuf
    104.     invoke  StdOut,addr lf
    105.  
    106.     invoke  GetProcessMemoryInfo, hProcess, ADDR pmc, SIZEOF pmc
    107.     mov eax, pmc.WorkingSetSize
    108.     invoke  wsprintf,addr TextBuf,addr template2,eax
    109.     invoke  StdOut,addr TextBuf
    110.     invoke  StdOut,addr lf
    111.  
    112.         invoke  StdIn, addr input_buffer, 1
    113. ;*******************************************************************
    114.     invoke  ExitProcess,0
    115. end main
    Результат :

    [​IMG]

    Из картинки вопрос - где повисли 708608 - 684032 = 24576 byte??
    Подскажите пожалуйста, может я чего накосячил.
    По выгрузке всех dll - вообще-то ожидалось
    объем занимаемой памяти = 684032 byte.
     
  2. spa

    spa Active Member

    Публикаций:
    0
    Регистрация:
    9 мар 2005
    Сообщения:
    2.240
    _sheva740
    текут поди7
     
  3. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Так что значит есть такое, или я где-то тормознул?

    Вот код dll - лек, (все три одинаковые):
    Код (Text):
    1. .386
    2. .model flat,stdcall
    3. option casemap:none
    4.     include \masm32\include\windows.inc
    5.     include \masm32\include\kernel32.inc
    6.     includelib \masm32\lib\kernel32.lib
    7. .data
    8.     szlibName       db 'MyFirstlib_01',0
    9.     szlibLoad       db 'lib Rule!_01',0
    10.     szlibUnLoad db 'Later, Bye Bye_01',0
    11. .code
    12. DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved:DWORD
    13.     mov  eax,TRUE
    14.     ret
    15. DllEntry Endp
    16. ;--------------------------------------------------------------
    17. Namez proc
    18.     lea eax, szlibName
    19.     ret
    20. Namez endp
    21. ;--------------------------------------------------------------
    22. Load proc
    23.     lea eax, szlibLoad
    24.     ret
    25. Load endp
    26. ;--------------------------------------------------------------
    27. Unload proc
    28.     lea eax, szlibUnLoad
    29.     ret
    30. Unload endp
    31. ;--------------------------------------------------------------
    32. End DllEntry
     
  4. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    _sheva740
    Попробуй перед ExitProcess повторить все вызовы ещё раз. И дай посмотреть на результаты.
     
  5. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Извини не понял, еще раз три строки с FreeLibruary() ?
    То есть Освободить либы замерять память и снова освободить либы?
    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\kernel32.inc
    7. include \masm32\include\user32.inc
    8. include \masm32\include\masm32.inc
    9.  
    10. includelib \masm32\lib\user32.lib
    11. includelib \masm32\lib\kernel32.lib
    12. includelib \masm32\lib\masm32.lib
    13.  
    14. include \masm32\include\psapi.inc
    15. includelib \masm32\lib\psapi.lib
    16.  
    17. .data
    18.     PROCESS_MEMORY_COUNTERS STRUCT
    19.         cb                          DWORD ?
    20.         PageFaultCount              DWORD ?
    21.         PeakWorkingSetSize          DWORD ?
    22.         WorkingSetSize              DWORD ?
    23.         QuotaPeakPagedPoolUsage     DWORD ?
    24.         QuotaPagedPoolUsage         DWORD ?
    25.         QuotaPeakNonPagedPoolUsage  DWORD ?
    26.         QuotaNonPagedPoolUsage      DWORD ?
    27.         PagefileUsage               DWORD ?
    28.         PeakPagefileUsage           DWORD ?
    29.     PROCESS_MEMORY_COUNTERS ENDS
    30.  
    31.     pmc PROCESS_MEMORY_COUNTERS  <>
    32.  
    33.     szlib00     db 'lib00.dll',0
    34.     szlib01     db 'lib01.dll',0
    35.     szlib02     db 'lib02.dll',0
    36.  
    37.     hlib00      dd 0
    38.     hlib01      dd 0
    39.     hlib02      dd 0
    40.     hProcess        dd 0
    41.  
    42.     template        db "   Loading Libs : %s",13,10,0
    43.     template1       db "   UnLoading Libs : %s",13,10,0
    44.     template2       db "   Process use : %d   byte",13,10,0
    45.     template3       db "   Second Libs UnLoading : %s",13,10,0
    46.  
    47.     TextBuf     db 100 dup( ? )
    48.  
    49.     input_buffer    db 2 dup(0)
    50.  
    51.     lf      db 13,10,0
    52.  
    53. .code
    54. main:
    55. ;*******************************************************************
    56.     invoke  GetCurrentProcess
    57.     mov hProcess, eax
    58.  
    59.     invoke  StdOut,addr lf
    60.     invoke  GetProcessMemoryInfo, hProcess, ADDR pmc, SIZEOF pmc
    61.     mov eax, pmc.WorkingSetSize
    62.     invoke  wsprintf,addr TextBuf,addr template2,eax
    63.     invoke  StdOut,addr TextBuf
    64.     invoke  StdOut,addr lf
    65.  
    66.     invoke  LoadLibrary,addr szlib00
    67.     mov hlib00,eax
    68.  
    69.     invoke  wsprintf,addr TextBuf,addr template,addr szlib00
    70.     invoke  StdOut,addr TextBuf
    71.  
    72.     invoke  LoadLibrary,addr szlib01
    73.     mov hlib01,eax
    74.  
    75.     invoke  wsprintf,addr TextBuf,addr template,addr szlib01
    76.     invoke  StdOut,addr TextBuf
    77.  
    78.     invoke  LoadLibrary,addr szlib02
    79.     mov hlib02,eax
    80.  
    81.     invoke  wsprintf,addr TextBuf,addr template,addr szlib02
    82.     invoke  StdOut,addr TextBuf
    83.  
    84.     invoke  StdOut,addr lf
    85.     invoke  GetProcessMemoryInfo, hProcess, ADDR pmc, SIZEOF pmc
    86.     mov eax, pmc.WorkingSetSize
    87.     invoke  wsprintf,addr TextBuf,addr template2,eax
    88.     invoke  StdOut,addr TextBuf
    89.     invoke  StdOut,addr lf
    90.  
    91.  
    92.     invoke  Sleep, 1000
    93.  
    94.  
    95.     invoke  FreeLibrary,hlib02
    96.     invoke  wsprintf,addr TextBuf,addr template1,addr szlib02
    97.     invoke  StdOut,addr TextBuf
    98.  
    99.     invoke  FreeLibrary,hlib01
    100.     invoke  wsprintf,addr TextBuf,addr template1,addr szlib01
    101.     invoke  StdOut,addr TextBuf
    102.  
    103.     invoke  FreeLibrary,hlib00
    104.     invoke  wsprintf,addr TextBuf,addr template1,addr szlib00
    105.     invoke  StdOut,addr TextBuf
    106.     invoke  StdOut,addr lf
    107.  
    108.     invoke  GetProcessMemoryInfo, hProcess, ADDR pmc, SIZEOF pmc
    109.     mov eax, pmc.WorkingSetSize
    110.     invoke  wsprintf,addr TextBuf,addr template2,eax
    111.     invoke  StdOut,addr TextBuf
    112.     invoke  StdOut,addr lf
    113.  
    114.     invoke  Sleep, 1000
    115.  
    116.     invoke  FreeLibrary,hlib02
    117.     invoke  wsprintf,addr TextBuf,addr template3,addr szlib02
    118.     invoke  StdOut,addr TextBuf
    119.  
    120.     invoke  FreeLibrary,hlib01
    121.     invoke  wsprintf,addr TextBuf,addr template3,addr szlib01
    122.     invoke  StdOut,addr TextBuf
    123.  
    124.     invoke  FreeLibrary,hlib00
    125.     invoke  wsprintf,addr TextBuf,addr template3,addr szlib00
    126.     invoke  StdOut,addr TextBuf
    127.     invoke  StdOut,addr lf
    128.  
    129.  
    130.     invoke  GetProcessMemoryInfo, hProcess, ADDR pmc, SIZEOF pmc
    131.     mov eax, pmc.WorkingSetSize
    132.     invoke  wsprintf,addr TextBuf,addr template2,eax
    133.     invoke  StdOut,addr TextBuf
    134.     invoke  StdOut,addr lf
    135.  
    136.  
    137.         invoke  StdIn, addr input_buffer, 1
    138. ;*******************************************************************
    139.     invoke  ExitProcess,0
    140. end main
    Вот:

    [​IMG]
     
  6. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    _sheva740
    Не так)
    Добавь не только FreeLibruary, а ещё и LoadLibrary.

    ЗЫ. Из консоли можно текст копировать в буфер обмена (правая кнопа).
     
  7. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    T800
    А понял вот:

    [​IMG]
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Жалких 6 страничек - да где угодно, в "недрах системы" :) WorkingSetSize это вообще фикция, на которую не стоит обращать внимания. Вызови EmptyWorkingSet или SetProcessWorkingSetSize(...,-1,-1) и будет тебе счастие ;)
     
  9. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Да-а-а ...

    [​IMG]

    Жаль что так нельзя с деньгами )))
    Спасибо за помощь!
     
  10. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    leo
    А куда тогда смотреть чтобы малость что-то контролировать?
     
  11. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    _sheva740
    А что вы хотите контролировать? Свои утечки памяти?
     
  12. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    T800
    Ну да, функцию какую-то типа GetProcessMemoryInfo()
    хотел в цикле, в отдельно потоке, гонять.
     
  13. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    _sheva740
    Мне не понятно для чАво вам проверять самого себя на ошибки, коли пишите на асме?
    Переходите на C/C++/Delphi и юзайте манагеры памяти, которые всё расскажут вам.
     
  14. gloomdemon

    gloomdemon New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2011
    Сообщения:
    5
    По поводу FreeLibrary, она не выгружает dll, а только уменьшает счетчик ссылок на библиотеку, если их не остается то библиотека выгружается системой. Поэтому не обязательно что библиотека будет выгружена из памяти.
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    В данном случае dll "выгружаются" - на картинке #7 видно, что после FreeLibrary раб.набор уменьшается, но не до исходного значения, т.к. помимо образов самих dll при их загрузке система может выделять доп.память на всякую обслугу (например, под таблицы страниц, Ldr-инфу о загруженных модулях и т.п.). Эти служебные страницы ес-но тоже включаются в WorkingSetSize (как общее кол-во физ.памяти, используемой процессом в наст.момент). Однако если физ.памяти достаточно, то хитрая винда может и не спешить их исключать\удалять из процесса в надежде, что они могут понадобиться в дальнейшем. К тому же при загрузке и инициализации одних dll может произойти подкачка\маппинг страниц других dll - системных, и эти ранее ни используемые страницы ес-но так и останутся в раб.наборе. И т.д. и т.п. Одним словом - такая "ветренная" штука как кол-во страниц физ.памяти, замапленных сиеминутно в процесс, никак не может служить хар-кой утечек\неутечек памяти (по вине программера).
     
  16. _sheva740

    _sheva740 New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    1.539
    Адрес:
    Poland
    Ну как "чАво" ))) надо же рачительно относиться к ресурсам )))
    Дело в том что в данном случае как раз предпринимается
    попытка переписать код с С++ на asm.
    Подскажите пожалуйста направление или апишки чтобы определять
    эти утечки. У меня на пример выше Deleaker Standalone Version 2.2.7.0
    вообще не отреагировал.
    Или единственно здравый подход тут - "махнуть рукой" и не заморачиваться?