Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.01 c
15-1150939130
vidiv
2006-06-22 05:18
2006.07.30
Высшее образование


2-1152527956
Postalll
2006-07-10 14:39
2006.07.30
Delphi & ADO


1-1150292191
Megabyte
2006-06-14 17:36
2006.07.30
Изменение формата ячеек Экселя в Дельфи


2-1152311962
SerJaNT
2006-07-08 02:39
2006.07.30
ZeosLib


2-1152078984
silvestr
2006-07-05 09:56
2006.07.30
Как вытащить имя файла без расширения ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский