안녕하세요.
정적으로 Dll 파일을 호출하여 해제하면 메모리에 재대로 해제 되는 것
같은 되요 동적으로 생성해서 호출 하면 계속 메모리가 8k 정도 증가 하내요.
제가 동적 호출에서 뭘 잘 못하고 있는 건가요?
아래는 동적 호출하는 부분입니다.
procedure TForm1.Button1Click(Sender: TObject);
type
TProc = procedure; stdcall;
var
Handle : THandle;
MyProc : TProc;
begin
Handle := LoadLibrary('DllHelp.dll');
@MyProc := GetProcAddress(Handle,'frmHelpShowModal');
MyProc;
FreeMemory(@MyProc);
FreeLibrary(Handle);
end;
이문제는 델파이도 같아요
즉, DLL 내부에서 DLL_PROCESS_DETACH 할때 별도의 작업을
해야 한다는 겁니다.
어차피 어플이 종료될때는 같이 없어집니다.
그러나 메인어플에서 반복적으로 Load와 Free를 한다면 문제이겠죠
Symptom:
R&D have confirmed that DLL's created with PB/DLL 6.x, and which are explicitly loaded and unloaded repeatedly (using the LoadLibrary() and FreeLibrary() API calls), may experience a small memory leak, equal to the size of the environment table (typically around 1.5Kb) with each DLL load/unload cycle. The problem is evident on the Windows NT/2000/XP platforms only.
The accumulated leak is fully cleared when the main application (Process) terminates, but low memory conditions can occur if a very large number of load/unload cycles occurs in that time.
Cause:
The cause of the leak has been traced to a failure of the DLL to release the memory held by its [local] copy of the environment strings table, at the point when the DLL unloads.
Important: The problem affects only applications that load such DLL's in a repeated and dynamic manner. Implicitly linked DLL's will not be a source of problems as memory is released correctly during process termination.
Solution:
Inserting a small procedure into LIBMAIN/DLLMAIN function can solve the problem. An example DLL code template follows:
#COMPILE DLL#DIM ALL DECLARE FUNCTION FreeEnvironmentStrings LIB "KERNEL32.DLL" _ ALIAS "FreeEnvironmentStringsA" (lpsz AS ASCIIZ) AS LONG%DLL_PROCESS_DETACH = 0 FUNCTION LIBMAIN (BYVAL hInstance AS LONG, _ BYVAL wReason AS LONG, _ BYVAL wHeapSize AS LONG) EXPORT AS LONG DIM x& IF wReason = %DLL_PROCESS_DETACH THEN x& = 0 DIALOG DOEVENTS ! mov eax, [ebx][&h6C] ! mov x&, eax CALL FreeEnvironmentStrings(BYVAL x&) END IF LIBMAIN = 1END FUNCTION
Note: PowerBASIC will be incorporating this correction into all future versions of the compiler