DLL- Heap aufräumen oder nicht?



  • Liebe Leute,

    bin grad am Release meiner ersten selbstgebastelten DLL und frage mich, was ich mit den Lookuptables machen soll, die ich beim Gebrauch der DLL aufgebaut habe.
    Wenn ich mehrfach auf die DLL zugreife, resize ich den Heapgebrauch anscheinend korrekt.
    Wenn ich allerdings mit FreeLibrary die DLL von Bord werfe, kriege ich beim Debuggen den Hinweis, daß MemoryLeaks bestehen. Insoweit richtig, als daß ich die Tables ja nicht lösche, sondern mich darauf verlasse, daß Win den ganzen Speicher der DLL putzt.

    Soll ich jetzt noch eine Aufräumfunktion schreiben oder genügt es, sich auf das Speichermanagement von Win zu verlassen?
    Welche Vor- und Nachteile ergeben sich jeweils aus den Vorgehensweisen - außer, daß ich beim Nichtaufräumen keine anderen Leaks mehr sehe?



  • Unbedingt selbst freigeben. Danach die DLL entladen.
    Simon

    Edit:
    Nicht aufräumen ist KEINE Option!



  • theta schrieb:

    Nicht aufräumen ist KEINE Option!

    Warum? Nur, damit pointercrash es übt? Weils Rechenzeit braucht? Weil wir selber immer aufräumen und es unfair ist, wenn pointercrash schummelt? Oder kann er sich aufs Speichermanagement von Win hier nicht verlassen?



  • volkard schrieb:

    theta schrieb:

    Nicht aufräumen ist KEINE Option!

    Warum? Nur, damit pointercrash es übt? Weils Rechenzeit braucht? Weil wir selber immer aufräumen und es unfair ist, wenn pointercrash schummelt?

    Nein, weil sonst Lecks entstehen. Offensichtlich will pointercrash die Dll entladen, ohne den Prozess zu beenden (sonst bräuchte es den Aufruf von FreeLibrary nicht).



  • Mox schrieb:

    Nein, weil sonst Lecks entstehen. Offensichtlich will pointercrash die Dll entladen, ohne den Prozess zu beenden (sonst bräuchte es den Aufruf von FreeLibrary nicht).

    Ich will sie ja gar nicht entladen. Ich will sie nur für Win gebrauchsfertig machen. Das Ding kann entladen werden, wenn die Konverterfunktion (ist ein Dateikonverter) ihren Rückgabewert abgeliefert hat, aber das ist kein Zwang.

    Wenn sie geladen bleibt, passiert nichts Böses, als Applikation auf einem Controller bleibt sie auch beim wievieltausendesten Durchlauf am Leben und ab dem Reset startet sowieso alles bei Null.
    Nur - es geht ja um nicht viel, nur um die DLL- Sache: Muß ich den ganzen Müll besser vorher händisch plattmachen oder hab' ich einfach was falsch verstanden?
    Win macht ja den ganzen Speicherkontext der DLL beim Entladen weg und treibt den Rest mit Ende der Applikation ab. Oder täusche ich mich da?



  • pointercrash() schrieb:

    Win macht ja den ganzen Speicherkontext der DLL beim Entladen weg ...

    Das bezieht sich nur auf den Speicher, der unmittelbar mit dem Laden und Entladen einer DLL gebraucht wird.
    Allen Gerüchten zum Trotze verfügt das Betriebssystem über keinen eingebauten GC.



  • Wozu soll sonst DllMain dienen, wenn nicht auch zum Aufräumen? daddeldu



  • +gjm+ schrieb:

    pointercrash() schrieb:

    Win macht ja den ganzen Speicherkontext der DLL beim Entladen weg ...

    Das bezieht sich nur auf den Speicher, der unmittelbar mit dem Laden und Entladen einer DLL gebraucht wird.
    Allen Gerüchten zum Trotze verfügt das Betriebssystem über keinen eingebauten GC.

    Was? Echt so schlimm? Mit einem GC hat das nix zu tun,

    MSDN schrieb:

    or the process terminates, the system unloads the module from the address space of the process. Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the library module an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process.

    ... aber "resources allocated on behalf of the current process" versteh' ich jetzt einfach nicht. Dann wär' das ja jenseits jeden Witzes, wenn es keinen lokalen Heap gäbe, der nur im Kontext der DLL existieren würde.

    Also bliebe der Speicher im Heap auch nach unload der DLL reserviert - wofür?



  • berniebutt schrieb:

    Wozu soll sonst DllMain dienen, wenn nicht auch zum Aufräumen? daddeldu

    Ich habe keine Ahnung, deswegen frage ich ja euch. Ich bin nur etwas verblüfft, daß man einem OS heute noch den Hintern manuell auswischen muß. Ich dachte, daß sich win seit NT selbst von vollgekackten Windeln freimachen kann.



  • pointercrash() schrieb:

    ... aber "resources allocated on behalf of the current process" versteh' ich jetzt einfach nicht.

    Grob übersetzt heißt das wirklich, daß die DLL ihre vollgekackten Windeln gefälligst selbst "beseitigen" soll. 🙂

    pointercrash() schrieb:

    Dann wär' das ja jenseits jeden Witzes, wenn es keinen lokalen Heap gäbe, der nur im Kontext der DLL existieren würde.

    Das OS unterscheidet nicht mehr zwischen "lokalem" oder "globalem" Heap. Eine Unterscheidung hätte auch erhebliche Nachteile für ein effizientes Speichermanagement. Allerdings kann man globale Variablen in der DLL als "lokalen" Heap betrachten (ist aber nicht zu empfehlen).

    pointercrash() schrieb:

    Ich bin nur etwas verblüfft, daß man einem OS heute noch den Hintern manuell auswischen muß.

    Nun, der Fortschritt besteht schon mal darin, daß man LoadLibrary () nicht auch noch mit einem "Handle" zum Speicher aufrufen muß (der dann hinterher auch wieder freigegeben werden muß). Ich persönlich fände es eher erschreckend wenn ein OS auf das Byte genau weiß, wieviel Speicher eine DLL/EXE benötigen wird. Und zwar vor dem laden schon.



  • +gjm+ schrieb:

    Ich persönlich fände es eher erschreckend wenn ein OS auf das Byte genau weiß, wieviel Speicher eine DLL/EXE benötigen wird. Und zwar vor dem laden schon.

    Mich persönlich schockiert eher, daß Win nicht weiß, was es mit dem Entladen einer DLL alles aus dem Speicher kippen kann.
    Mich verunsichert volkards Eintrag zusätzlich, nachdem ich gar nix machen müßte - aber was soll's?

    Also gut, die Tables werden explizit gekillt - ob das aber wirklich nötig ist, interessiert mich natürlich weiterhin.



  • pointercrash() schrieb:

    Mich verunsichert volkards Eintrag zusätzlich, nachdem ich gar nix machen müßte - aber was soll's?

    Kam falsch rüber. Ich wollte eine Klarstellung bekommen, ob es nur guter Stil ist oder ob es echt notwendig ist.



  • nimm nicht malloc/free, sondern z.b. diese funktionen: http://msdn.microsoft.com/en-us/library/aa366781(VS.85).aspx#heap_functions
    dann noch bei DLL_PROCESS_ATTACH und DLL_PROCESS_DETACH einen zähler mitlaufen lassen. geht er von 0 auf 1 (erster prozess connected sich mit der dll) dann mit HeapCreate() den heap erzeugen und wenn er von 1 auf 0 geht (alle prozesse weg), dann mit HeapDestroy() den heap wegschmeissen. nur vom prinzip her, könnte klappen. oder du macht es mit VirtualAlloc/VirtualFree.
    🙂



  • volkard schrieb:

    pointercrash() schrieb:

    Mich verunsichert volkards Eintrag zusätzlich, nachdem ich gar nix machen müßte - aber was soll's?

    Kam falsch rüber. Ich wollte eine Klarstellung bekommen, ob es nur guter Stil ist oder ob es echt notwendig ist.

    Nein, es ist selbstverständlich absolut nicht notwendig.
    Ist wie mit dem Geschirr, wenns dreckig ist und Du genug davon hast, kannst Du es auch einfach ungewaschen auf dem Tisch stehen lassen und hoffen, dass die Hausverwaltung spätestens bei deinem Auszug aufräumt.

    Ich persönlich mache es nicht so.

    Ich weiss nicht, ich finds ziemlich simpel: Alles was ich anfordere an Resourcen (Speicher, File Handles, etc.) gebe ich dann zurück wenn ich es nicht mehr benötige.

    Simon



  • pointercrash() schrieb:

    Also gut, die Tables werden explizit gekillt

    👍



  • pointercrash() schrieb:

    Mich persönlich schockiert eher, daß Win nicht weiß, was es mit dem Entladen einer DLL alles aus dem Speicher kippen kann.

    Der Heap, auf dem Du Deine Tabellen allokiert hast, ist eine Ressource des Prozesses. Und dieser Heap lebt bis zum Ende eben dieses Prozesses (wenn Du ihn zuvor nicht selber killst).

    Es wird nicht Buch darüber geführt, aus welchem Modul die allocs kamen. Und das ist auch gut so (weil's Rechenzeit und Platz braucht).

    Wenn Du es einfach haben willst, erstellst Du Dir Deinen eigenen Heap (HeapCreate). In DllMain kannst Du dann ganz einfach HeapDestroy aufrufen -> dann verschwindet auch alles das, was Du per HeapAlloc angefordert hast (Du sparst Dir damit die einzelnen HeapFrees).



  • Mox schrieb:

    Es wird nicht Buch darüber geführt, aus welchem Modul die allocs kamen. Und das ist auch gut so (weil's Rechenzeit und Platz braucht).

    Das ist vor allem deshalb gut so, weil ich den Speicher theoretisch im Prozess weiterverwenden kann, auch wenn die DLL explizit entladen wird.



  • theta schrieb:

    ... ich finds ziemlich simpel: Alles was ich anfordere an Resourcen (Speicher, File Handles, etc.) gebe ich dann zurück wenn ich es nicht mehr benötige.

    Das ist und bleibt guter Programmierstil, selbst wenn das System mit einigem alleine aufräumt! 😋



  • berniebutt schrieb:

    theta schrieb:

    ... ich finds ziemlich simpel: Alles was ich anfordere an Resourcen (Speicher, File Handles, etc.) gebe ich dann zurück wenn ich es nicht mehr benötige.

    Das ist und bleibt guter Programmierstil, selbst wenn das System mit einigem alleine aufräumt! 😋

    100% Ack.



  • berniebutt schrieb:

    theta schrieb:

    ... ich finds ziemlich simpel: Alles was ich anfordere an Resourcen (Speicher, File Handles, etc.) gebe ich dann zurück wenn ich es nicht mehr benötige.

    Das ist und bleibt guter Programmierstil, selbst wenn das System mit einigem alleine aufräumt! 😋

    Naja, ich hab' ja geschrieben, wo das Zeug herkommt, nämlich vom Controller und da störts nicht, wenns aufm Heap liegenbleibt, im Gegenteil, zwei der Tables werden noch benötigt.

    Im Allgemeinen ist es ja keine Frage des guten Stils, ob ich mir die Schläfe desinfiziere, bevor ich mir eine Kugel durch die Birne jage - das ist eher bizarr.

    Ein Teil der Funktionalität soll jedoch unter Win laufen und weil ich nicht gleich die Source hergeben mag, packe ich's in eine DLL und muß halt die Spielregeln von Win beachten.

    Also, da ich die Codebasis behalten möchte und mit HeapCreate dann auch alles auf HeapAlloc usw. umbiegen müßte, würde das zu einem heftigen #ifdef- Dschungel führen, dafür wäre nach HeapDestroy() die Landschaft wieder sauber.
    Wenn ich bei malloc/free bleibe, sollte ich hingegen selbst aufräumen - hab' ich das richtig verstanden? 😕

    Hab' mich mal wegen Tippfaulheit für zweiteres entschieden und jetzt drei Funktionen, die die DLL exportiert, ein Initialisierungsaufruf, der das Teil parametriert (und auch die Tabellen aufbaut), einen Aufruf zur Konvertierung und einen, der die Tabellen wieder abreißt.
    Ist damit den Win- Konventionen genüge getan? 😕


Anmelden zum Antworten