![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Утечка ПАМЯТИ & DLL [D6, WinXP]
lux_dn © (2006-06-17 17:21:00)Здравствуйте, ВСЕ!
Товарищи, я создаю проект, в котором используются плагины.
(в каждой DLL-ке находится форма).
Если выполнить следующие строчки кода из вызывающей программы
(ДАЖЕ НЕ ВЫЗЫВАЯ ФУНКЦИЮ "ShowMyDialog" из DLL)
LoadLibrary('plugin.dll');
а затем
FreeLibrary(DLL_Handle);
То, после выгрузки плагина видно, что каждый раз освобождается на 4 кб меньше, чем было первоначально.
Диспетчер задач -> Быстродействие -> Выделение памяти (Кб).
Т.е. программа "жрет" память.
Я бы закрыл на это глаза, но в моем проекте плагины могут загружаться по тысяче раз за сеанс.
Страшно представить, какая будет "утечка"!
Я думал, что дело в форме, которая в DLL и по-этому, ради эксперимента я:
1) удалил форму из DLL, перекомпилил - та же лажа...
2) Скопировал первую попавшуюся DLL-ку в папку, где программа и подгрузил ее - все ОК!
Получается, что DLL-ки, которые создает Делфя некорректно освобождают память???
У меня D6.
Откуда утечка памяти??
КАК ЛЕЧИТЬ, ПОМОГИТЕ!
;-------------------------------------------------------------
Вот пример плагина:
;-------------------------------------------------------------
library plugin;
uses
Windows, ..., plu in 'plu.pas' {Form1};
{$R *.res}
function ShowMyDialog(Msg: PChar): Boolean; stdcall;
begin
Form1 := TForm1.Create(Application);
Form1.Label1.Caption := StrPas(Msg);
Result := (Form1.ShowModal = mrOk);
Form1.Free;
end;
exports ShowMyDialog;
begin
end.
;-------------------------------------------------------------
и вызывающей программы
;-------------------------------------------------------------
var DLL_Handle:Thandle;
procedure TForm1.Button1Click(Sender: TObject);
begin
DLL_Handle := LoadLibrary('plugin.dll');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeLibrary(DLL_Handle);
end;
;-------------------------------------------------------------
lux_dn (2006-06-18 00:25:00) [1]Спасибо Всем!
А особенно, Leonid Troyanovsky, за то, что ткнул носом:))
Будем пробовать...
Eraser (2006-06-17 22:49:00) [2]> http://groups.google.com/group/fido7.ru.delphi/browse_thread/thread/6fa28
> 9946ef491e3/6dd1f6d37afa788d?#6dd1f6d37afa788d
а что если при динамической загрузке вызывать LoadLibrary только один раз, при первом вызове, как это сделано в jwa API от JEDI.
Например:
{$IFDEF DYNAMIC_LINK}
var
_CopyFile: Pointer;
function CopyFile;
begin
GetProcedureAddress(_CopyFile, kernel32, 'CopyFileA');
asm
mov esp, ebp
pop ebp
jmp [_CopyFile]
end;
end;
{$ELSE}
...
procedure GetProcedureAddress(var P: Pointer; const ModuleName, ProcName: string);
var
ModuleHandle: HMODULE;
begin
if not Assigned(P) then
begin
ModuleHandle := GetModuleHandle(PChar(ModuleName));
if ModuleHandle = 0 then
begin
ModuleHandle := LoadLibrary(PChar(ModuleName));
if ModuleHandle = 0 then raise EJwaLoadLibraryError.Create('Library not found: ' + ModuleName);
end;
P := GetProcAddress(ModuleHandle, PChar(ProcName));
if not Assigned(P) then raise EJwaGetProcAddressError.Create('Function not found: ' + ModuleName + '.' + ProcName);
end;
end;
хотя возможно специфика программы этого не позволит, т.к. dll всё таки является плагином.
Пусик (2006-06-17 22:33:00) [3]Так как всем интересно, даю прямую ссылку от LVT (самому трудно было дать?-))
http://groups.google.com/group/fido7.ru.delphi/browse_thread/thread/6fa289946ef491e3/6dd1f6d37afa788d?#6dd1f6d37afa788d
Leonid Troyanovsky (2006-06-17 20:58:00) [4]
> lux_dn © (17.06.06 20:30) [7]
Ответил в rsdn.
--
Regards, LVT.
lux_dn (2006-06-17 20:30:00) [5]
>Диспетчер задач не показывает утечки памяти. По крайней мере, в Delphi-программах, которые используют свой собственный менеджер памяти.
DrPass, а что тогда означает "Выделение памяти (Кб)" в Диспетчере задач?
Значение выделяемой памяти естественно увеличивается при
LoadLibrary('plugin.dll') и должно вернуться к прежней цифре при
FreeLibrary(DLL_Handle).
Оно как раз так и происходит, когда в USES библиотеки нет FORMS (см. пред. сообщение)
lux_dn (2006-06-17 20:13:00) [6]Товарищи, скоро буду волосы рвать на ... (неприличном месте)Ж))))
Оказалось, что если в DLL (в USES) включить FORMS, то происходит утечка!!!
Даже, просто с пустой DLL-кой (без формы).
Конечно, это показывает Диспетчер задач, а не MemProof, но все же ...
А если убрать FORMS - ВСЕ ОК!!!
Но у меня, как раз в ДЛЛ-ке форма лежит ... вот здесь как быть??
Товарищи, у кого какая версия дельфи, попробуйте, скажите ...
DrPass (2006-06-17 19:22:00) [7]
> но в моем проекте плагины могут загружаться по тысяче раз
> за сеанс.
100% аргумент для переделки механизма работы с плагинами. Плагин должен загружаться 1 раз при старте программы или при первом обращении.
> после выгрузки плагина видно, что каждый раз освобождается
> на 4 кб меньше
Диспетчер задач не показывает утечки памяти. По крайней мере, в Delphi-программах, которые используют свой собственный менеджер памяти.
TUser (2006-06-17 19:14:00) [8]Ну, пришли мне свой код.
lux_dn (2006-06-17 18:32:00) [9]В том-то и дело, что и я создавал пустую DLL!
Я еще один эксперимент провел, поставил на форму таймер, который (где-то 4 раза в секунду) нажимает на кнопки, т.е. загружает и выгружает dll (ну, чтобы самому не нажимать).
Где-то через минут 40, увидел мессадж, в котором написано, что приложение исчерпало все выделенные ресурсы.
Но по 4 кб теряется .... странно.... будем искать MemProof
TUser (2006-06-17 18:13:00) [10]Загрузка-выгрузка пустой dll (созданной dll визардом) не привела к утечке памяти. D7. Что за модули подключены в dll, может в них дело?
Eraser (2006-06-17 17:59:00) [11]> [0] lux_dn © (17.06.06 17:21)
что ж все так и наровят запихать форму и dll...? о размере проекта не беспокоитесь?
PS крод, на первый взгляд, правильный.
PPS гляньте в сторону MemProof, а
> Диспетчер задач -> Быстродействие -> Выделение памяти (Кб)
> .
- не показатель.