DLL laden/entladen



  • Dieser Thread wurde von Moderator/in akari aus dem Forum VCL (C++ Builder) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • 1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs hat nur was mit dem Installer zu tun.
    2. Das wird wohl in Deiner DLL liegen. Wenn die DLL beim Laden Speicher allokiert und diese beim Beenden nicht freigibt, so wird das eben darin liegen.



  • Hallo zusammen

    Das der Speicher von cFileName nicht freigegeben wird, ist mir auch schon aufgefallen, ist bereits korrigiert, jedoch dies sollte nicht das Problem sein.

    akari schrieb:

    Auch der Speicherverbrauch ist noch nicht ausssagekräftig, denn Windows behält sehr wohl aus Geschwindigkeitsgründen DLLs (oder Teile davon) im Speicher. Du solltest mal die Funktion mehrmals hintereinander ausführen, und schauen ob jedesmal der Gesamtverbrauch weiter steigt.

    Der Speicher steigt beim jedem Aufruf, bis irgendwann der Hauptspeicher voll ist.

    Martin Richter schrieb:

    1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs hat nur was mit dem Installer zu tun.

    Das mit der Registry habe ich nicht verstanden.
    Ich war seither der Meinung, daß die Anzahl wie oft eine DLL angefordert wurde immer in der Registry gespeichert wird. Dies wiederspricht deiner Aussage, und was meinst Du mit Installer?

    Martin Richter schrieb:

    2. Das wird wohl in Deiner DLL liegen. Wenn die DLL beim Laden Speicher allokiert und diese beim Beenden nicht freigibt, so wird das eben darin liegen.

    Das der Speicher _nicht_ in der DLL allokiert wird bin ich mir eigentlich zu 99% sicher, denn beim Laden der DLL passiert in der DLL noch gar nichts, und zu diesem Zeitpunkt steigt bereits der Speicherverbrauch an. Sobald die Funktion in der DLL ausgeführt wird ändert sich jedoch am Speicherverbrauch nichts.

    Noch irgendwelche Ideen?
    MfG Stephan



  • Stephan schrieb:

    Martin Richter schrieb:

    1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs hat nur was mit dem Installer zu tun.

    Das mit der Registry habe ich nicht verstanden.
    Ich war seither der Meinung, daß die Anzahl wie oft eine DLL angefordert wurde immer in der Registry gespeichert wird. Dies wiederspricht deiner Aussage, und was meinst Du mit Installer?

    Wenn mehrere Programm ein und die selbe DLL installieren, dann wird dies in diesem Ast mitgezählt wieviele Program diese DLL gemeinsam nutzen.
    Wird das ein Programm deinstalliert und der Zähler dieses Eintrages fällt auf 0 wird die DLL entfernt vom Rechner.

    Lies die MSDN bzgl. Installer und shared DLLs...

    Stephan schrieb:

    Martin Richter schrieb:

    2. Das wird wohl in Deiner DLL liegen. Wenn die DLL beim Laden Speicher allokiert und diese beim Beenden nicht freigibt, so wird das eben darin liegen.

    Das der Speicher _nicht_ in der DLL allokiert wird bin ich mir eigentlich zu 99% sicher, denn beim Laden der DLL passiert in der DLL noch gar nichts, und zu diesem Zeitpunkt steigt bereits der Speicherverbrauch an. Sobald die Funktion in der DLL ausgeführt wird ändert sich jedoch am Speicherverbrauch nichts.

    Irrtum! Evtl. solltest Du Dir erstmal die Basics über Dlls in der MSDN aneignen.

    Sobald die DLL geladen wird, werden auch andere mit dieser DLL verbundene DLs geladen. Jewels in jeder DLL wird DllMain ausgeführt. In diesem DllMain Code kann sehrwohl sofort Speicher allokiert werden.
    Gleiches beim entladen.

    Eine DLL kann sehr wohl nur durch das Laden Leaks verursachen wenn Sie schlecht programmiert wurde.



  • Hallo zusammen

    Martin Richter schrieb:

    Irrtum! Evtl. solltest Du Dir erstmal die Basics über Dlls in der MSDN aneignen.

    Sobald die DLL geladen wird, werden auch andere mit dieser DLL verbundene DLs geladen. Jewels in jeder DLL wird DllMain ausgeführt. In diesem DllMain Code kann sehrwohl sofort Speicher allokiert werden.
    Gleiches beim entladen.

    Eine DLL kann sehr wohl nur durch das Laden Leaks verursachen wenn Sie schlecht programmiert wurde.

    Das es möglich ist bereits beim Laden bzw Entladen Code auzuführen ist mir klar, allerdings macht dies meine DLL nicht, bzw ich habe keinen Code dafür geschrieben.
    Was ich im Ereignissprotokoll gesehen habe ist daß, eine weitere DLL (MSIMG32.dll) geladen wird. Nach kurzem googeln weiß ich nun das diese DLL von MS ist und etwas mit GDI zu tun hat.
    Ich gehe davon aus, daß diese DLL (MSIMG32.dll) soweit OK ist.

    MfG Stephan



  • Wenn Du die DLL selbst geschrieben hast.
    Frage 1: Wie sieht Dein DllMain Code aus
    Frage 2: Verwendset Du statische Objekte/Klassen, die beim Laden der DLL initialisiert werden? Wenn ja welche?
    Frage 3: Verwendest Du andere LIBs deren Code Du nutzt und deren FunktionsweiseDu evtl. nicht kennst.



  • Hallo zusammen

    Martin Richter schrieb:

    Frage 1: Wie sieht Dein DllMain Code aus

    Da ich CodGear 2009 (ehemals Borland) verwende, müßte dies mein Dllmain sein.

    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
        return 1;
    }
    

    Martin Richter schrieb:

    Frage 2: Verwendset Du statische Objekte/Klassen, die beim Laden der DLL initialisiert werden? Wenn ja welche?

    Es wird nur eine Klasse verwendet, welche ein statisches Objekt verwendet. Habe jedoch mit einer MessageBox überprüft, das der Destruktor aufgerufen wird. Die restlichen C-Dateien sind alles nur einzelne Funktionen, welche nach momentanem Wissensstand keine globalen Variablen verwenden.

    Martin Richter schrieb:

    Frage 3: Verwendest Du andere LIBs deren Code Du nutzt und deren FunktionsweiseDu evtl. nicht kennst.

    Ich verwende einen Satz externen Funktionen um einen MD5 Hash zu errechnen.
    Diese muß ich mir nochmals genau anschauen.

    MfG Stephan



  • Welche anderen DLLs werden durch diese DLL geladen und wieder entladen?



  • behebe erstmal das speicherleck. vielleicht bringts ja was.



  • Hallo zusammen

    Martin Richter schrieb:

    Welche anderen DLLs werden durch diese DLL geladen und wieder entladen?

    Es werden explizit keine anderen DLLs per Code von mir geladen. Was ich im Ereignissprotokoll sehe, ist das eine DLL MSIMG32.dll geladen wird, welche laut Google von MS kommt und etwas mit GDI zu tun hat.

    leck! schrieb:

    behebe erstmal das speicherleck. vielleicht bringts ja was.

    Von welchem Speicherleck redest Du?
    Wenn Du die Sache mit cFileName meinst, die ist schon lange erledigt.

    Meine neusten Erkenntnise sehen jedoch nun so aus, daß wenn ich im Linker die Verwendung der dynamischen RTL einstelle, das Problem behoben ist.
    Allerdings möchte ich die RTL nicht dynamisch verwenden, sondern statisch.

    Meiner Meinung nach ist dies dann ja nun doch ein Builder Problem, oder nicht?
    Wenn ihr dies genauso seht, bitte wieder zurück verschieben. Danke.

    Habe als weiteren Test eine neue DLL mit einer leeren Funktion erstellt und diese exportiert.
    Anschließend eine neue Anwendung welche mit einem Button die DLL dynamisch lädt (LoadLibrary) und wieder entläd (FreeLibrary).
    Wenn ich den Button nun mehrfach drücke sehe ich das der Speicherverbrauch wieder ansteigt.
    Sobald ich auf dynamische RTL umstelle funktioniert es wie es soll. Habe auch schon versucht wie angegeben MEMMGR.LIB mit zu linken. Jedoch ohne Veränderung.

    Bin momentan sehr ratlos.

    MfG Stephan



  • RTL?



  • Hallo Martin

    Martin Richter schrieb:

    RTL?

    Sorry, für alle nicht Builderanwender, hier geht es um die Laufzeitbibliotheken, deshalb auch die Vermutung, daß es sich hierbei um ein builderspezifische Problem handelt.
    Die Laufzeitbibliothek kann entweder dynamisch oder statisch gelinkt werden. Wobei, meiner Meinung nach, die meisten Builderanwender die statische Variante bervorzugen.

    MfG Stephan



  • Und Du bist sicher, dass der DllMain Entry Point stimmt, so dass der Builder seinen Init/Uninit durchführen kann.

    Wennm man in einem MS Produkt, den Entry-Point der DLL selbst verbiegt unddie CRT umgeht, gibt es auch Leaks, wenn man dann doch die CRT benutzt!



  • Hallo Martin

    Das der Entry Point stimmt bin ich mir eigentlich sicher, da der Builder den Code automatisch erstellt, und ich hier nichts geändert habe.
    Mit der CRT meinst Du die Runtime Library, oder?

    Kann der Beitrag wieder zurück ins Builder Forum verschoben werden, oder ist dies Technisch nicht möglich?

    MfG Stephan



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum WinAPI in das Forum VCL (C++ Builder) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ja mit CRT meine ich die C Runtime Library.

    Ich habe den Beitrag verschoben! Viel Glück bei der weiteren Suche.



  • Hallo zusammen

    @Martin Richter
    Vielen dank für dein Hilfe, und ich glaube Glück kann ich gebrauchen 😉

    Also ich bin wieder da mit meinem Problem, denn so wie es aussieht, hat es etwas mit dem Builder.

    Nochmals eine kurze Zusammenfassung:
    Sobald ich eine DLL (erstellt mit CG2009 und statischer RTL) dynamisch in einem Projekt (CG2009) lade und wieder entlade (mehrfach) steigt der Speicherverbrauch immer weiter an. Nach jedem entladen bleiben ca. 1,2 MB übrig.
    Habe DLL und Anwendung schon mit MEMMGR.LIB sowie ohne erstellt, jedoch ohne Erfolg.
    Wenn die DLL mit dynamischer RTL erstellt wird, funktioniert alles wie es soll.

    Kann dies jemand erklären, bzw bei sich nachvollziehen?

    Bin langsam mehr als ratlos.

    MfG Stephan



  • //---------------------------------------------------------------------------
    //   Wichtiger Hinweis zur DLL-Speicherverwaltung, falls die DLL die statische
    //   Version der Laufzeitbibliothek (RTL) verwendet:
    //
    //   Wenn die DLL Funktionen exportiert, die String-Objekte (oder Strukturen/
    //   Klassen, die verschachtelte Strings enthalten) als Parameter oder Funktionsergebnisse übergibt,
    //   muß die Bibliothek MEMMGR.LIB im DLL-Projekt und anderen Projekten,
    //   die die DLL verwenden, vorhanden sein. Sie benötigen MEMMGR.LIB auch dann,
    //   wenn andere Projekte, die die DLL verwenden, new- oder delete-Operationen
    //   auf Klassen anwenden, die nicht von TObject abgeleitet sind und die aus der DLL exportiert
    //   werden. Durch das Hinzufügen von MEMMGR.LIB wird die DLL und deren aufrufende EXEs
    //   angewiesen, BORLNDMM.DLL als Speicherverwaltung zu benutzen. In diesem Fall
    //   sollte die Datei BORLNDMM.DLL zusammen mit der DLL weitergegeben werden.
    //
    //   Um die Verwendung von BORLNDMM.DLL, zu vermeiden, sollten String-Informationen als "char *" oder
    //   ShortString-Parameter weitergegeben werden.
    //
    //   Falls die DLL die dynamische Version der RTL verwendet, müssen Sie
    //   MEMMGR.LIB nicht explizit angeben.
    //---------------------------------------------------------------------------
    

    Das steht bei jedem neuem DLL Projekt dabei, das man mit BCB6 erstellt. Hast du dich daran gehalten? Da du ja die statische Version der RTL verwenden möchtest.

    mfg



  • Hallo zusammen

    RTL schrieb:

    Das steht bei jedem neuem DLL Projekt dabei, das man mit BCB6 erstellt. Hast du dich daran gehalten? Da du ja die statische Version der RTL verwenden möchtest.mfg

    Stephan schrieb:

    Habe DLL und Anwendung schon mit MEMMGR.LIB sowie ohne erstellt, jedoch ohne Erfolg.

    Wie ich bereits schon mehrfach geschrieben habe, habe ich es mit der MEMMGR.LIB versucht sowie ohne.

    Außerdem ist mir nicht ganz klar ob diese Einschränkung nur dann gilt, wenn ich Klassen bzw VCL Datentypen exportiere.
    Die bisherige DLL, welche ich nun zum Testen dieses Problems verwende, hat nur eine exportierte Funktion, ohne VCL Datentypen, und es wird keine Funktion aufgerufen, sondern die DLL nur geladen und entladen.

    MfG Stephan



  • Hallo zusammen

    Habe unter http://support.codegear.com/article/38487#knownproblems folgenden Hinweis gefunden.

    Dynamische Link-RTL kann beim dynamischen Laden einer DLL nicht verwendet werden

    Wenn Sie eine DLL dynamisch laden, können Sie sie nicht dynamisch mit der Laufzeitbibliothek linken. Ansonsten tritt eine Zugriffsverletzung bei Programmende auf. Deaktivieren Sie zur Lösung des Problems die Option Dynamische RTL auf der Seite Linker des Dialogfeldes Projektoptionen.

    Das heißt doch, daß genau der Fall, welcher bei mir funktioniert (DLL dynamisch laden, RTL dynamisch linken) einen Fehler verursachen soll. Oder habe ich dies falsch verstanden?

    MfG Stephan


Anmelden zum Antworten