Форум: "Основная";
Текущий архив: 2006.07.30;
Скачать: [xml.tar.bz2];
ВнизУтечка ПАМЯТИ & 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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.012 c