Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.07.30;
Скачать: CL | DM;

Вниз

Утечка ПАМЯТИ & DLL   Найти похожие ветки 

 
lux_dn ©   (2006-06-17 17:21) [0]

Здравствуйте, ВСЕ!

Товарищи, я создаю проект, в котором используются плагины.
(в каждой 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;

;-------------------------------------------------------------


 
Eraser ©   (2006-06-17 17:59) [1]

> [0] lux_dn ©   (17.06.06 17:21)

что ж все так и наровят запихать форму и dll...? о размере проекта не беспокоитесь?

PS крод, на первый взгляд, правильный.
PPS гляньте в сторону MemProof, а

> Диспетчер задач -> Быстродействие  -> Выделение памяти (Кб)
> .

- не показатель.


 
TUser ©   (2006-06-17 18:13) [2]

Загрузка-выгрузка пустой dll (созданной dll визардом) не привела к утечке памяти. D7. Что за модули подключены в dll, может в них дело?


 
lux_dn ©   (2006-06-17 18:32) [3]

В том-то и дело, что и я создавал пустую DLL!

Я еще один эксперимент провел, поставил на форму таймер, который (где-то 4 раза в секунду) нажимает на кнопки, т.е. загружает и выгружает dll (ну, чтобы самому не нажимать).
Где-то через минут 40, увидел мессадж, в котором написано, что приложение исчерпало все выделенные ресурсы.

Но по 4 кб теряется .... странно.... будем искать MemProof


 
TUser ©   (2006-06-17 19:14) [4]

Ну, пришли мне свой код.


 
DrPass ©   (2006-06-17 19:22) [5]


> но в моем проекте плагины могут загружаться по тысяче раз
> за сеанс.

100% аргумент для переделки механизма работы с плагинами. Плагин должен загружаться 1 раз при старте программы или при первом обращении.

> после выгрузки плагина видно, что каждый раз освобождается
> на 4 кб меньше

Диспетчер задач не показывает утечки памяти. По крайней мере, в Delphi-программах, которые используют свой собственный менеджер памяти.


 
lux_dn ©   (2006-06-17 20:13) [6]

Товарищи, скоро буду волосы рвать на ... (неприличном месте)Ж))))

Оказалось, что если в DLL (в USES) включить FORMS, то происходит утечка!!!
Даже, просто с пустой DLL-кой (без формы).
Конечно, это показывает Диспетчер задач, а не MemProof, но все же ...

А если убрать FORMS - ВСЕ ОК!!!

Но у меня, как раз в ДЛЛ-ке форма лежит ... вот здесь как быть??
Товарищи, у кого какая версия дельфи, попробуйте, скажите ...


 
lux_dn ©   (2006-06-17 20:30) [7]


>Диспетчер задач не показывает утечки памяти. По крайней мере, в Delphi-программах, которые используют свой собственный менеджер памяти.


DrPass, а что тогда означает "Выделение памяти (Кб)" в Диспетчере задач?

Значение выделяемой памяти естественно увеличивается при
LoadLibrary("plugin.dll") и должно вернуться к прежней цифре при
FreeLibrary(DLL_Handle).

Оно как раз так и происходит, когда в USES библиотеки нет FORMS (см. пред. сообщение)


 
Leonid Troyanovsky ©   (2006-06-17 20:58) [8]


> lux_dn ©   (17.06.06 20:30) [7]


Ответил в rsdn.

--
Regards, LVT.


 
Пусик ©   (2006-06-17 22:33) [9]

Так как всем интересно, даю прямую ссылку от LVT (самому трудно было дать?-))

http://groups.google.com/group/fido7.ru.delphi/browse_thread/thread/6fa289946ef491e3/6dd1f6d37afa788d?#6dd1f6d37afa788d


 
Eraser ©   (2006-06-17 22:49) [10]

> 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 всё таки является плагином.


 
lux_dn ©   (2006-06-18 00:25) [11]

Спасибо Всем!
А особенно, Leonid Troyanovsky, за то, что ткнул носом:))
Будем пробовать...



Страницы: 1 вся ветка

Текущий архив: 2006.07.30;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.025 c
3-1147361563
Neo Trinitron
2006-05-11 19:32
2006.07.30
TOracleDataset,RefreshRecord глюк.


15-1151405664
ArtemESC
2006-06-27 14:54
2006.07.30
Мышак в DrDos e..


3-1148563915
_RusLAN
2006-05-25 17:31
2006.07.30
Связка TIBQuery + TDBGridEh + TUpdateSQLW. Подправить даные.


2-1152259668
0bsid
2006-07-07 12:07
2006.07.30
Память и виртуальная память


3-1148743113
Sword
2006-05-27 19:18
2006.07.30
Fast report и два запроса