MemLeak in Max2D?
Übersicht

![]() |
HolzchopfMeisterpackerBetreff: MemLeak in Max2D? |
![]() Antworten mit Zitat ![]() |
---|---|---|
Guten Morgen liebe BlitzMax-Fangemeinde! Heute geht's mal früh zur Sache:
Folgendes: Ich hatte gestern erfolglos versucht, die Ramauslastung in einem BMax-Programm nach unten zu drücken... Irgendwann kam ich zum Entschluss: Entweder, ich mache etwas gehörig falsch, oder Max2D resp DrawImage verursacht irgendwo ein Memory Leak. Als Demonstration habe ich folgenden Code. Er erstellt ein 400x300px Bild mit 20 Frames, die im Sekundentakt gewechselt werden. Laut meiner Rechnung sollte das ~10MiB RAM füllen. Aber - und das ist seltsam - jedes Frame, das zum ersten mal auf dem Bildschirm gezeichnet wird, lässt die Auslastung gute 2MiB nach oben schnellen =/ Insgesamt gehts bei mir auf 57MiB... BlitzMax: [AUSKLAPPEN] SuperStrict Passiert bei euch das gleiche? Selber Effekt? Selbe (Aus-)Wirkung? Habe BMax 1.33 Und wenn ja: Hat jemand eine Idee, was man dagegen tun könnte? =( mfG Edit Es macht übrigens bei mir keinen Unterschied, ob ich nun BlitzMax: [AUSKLAPPEN] Framework BRL.GlMax2D
oder auch BlitzMax: [AUSKLAPPEN] Framework BRL.D3D7Max2D
verwende =/ |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
AvaGast |
![]() Antworten mit Zitat |
|
---|---|---|
Vermutung liegt nahe, dass ein DynamicImage sowohl die Pixmap, als auch das Image speichert - und somit etwa doppelten Speicher verbraucht. Das würde auch erklären, warum der Speicherbedarf beim ersten Zeichnen steigt: Er läd die Pixmap als Image hoch (aktualisiert es quasi).
So ist das zumindest bei meiner GFX-Engine. ![]() (Habe jetzt aber noch nicht direkt in den Source geschaut, um diese Vermutung abzusichern ^^) |
||
![]() |
Nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habs jetzt auch mal getestet und bin zu folgendem Ergebnis gekommen:
GLMax2D: ca. 60 MiB D3D7Max2D: ca. 36 MiB D3D9Max2D: ca. 40 MiB |
||
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7 |
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
@ Ava: Das könnte eine Erklärung sein. Zumindest so halb. Denn ein 400x300 Pixmap sollte keine 2MiB beanspruchen. Und doppelter Speicherverbrauch find' ich sowieso grad mal ziemlich ungünstig ![]() Aber um der DYNAMICIMAGE-Theorie nachzugehen, habe ich mal ein 400x300 Bild mit 20Frames erstellt, abgespeichert und mit verschiedenen Flags bei LoadAnimImage geladen und folgendes beobachtet: Code: [AUSKLAPPEN] OpenGL
DYNAMICIMAGE 69MiB FILTEREDIMAGE 69MiB MASKEDIMAGE 72MiB MIPMAPPEDIMAGE 56MiB D3D7 DYNAMICIMAGE 58MiB FILTEREDIMAGE 58MiB MASKEDIMAGE 61MiB MIPMAPPEDIMAGE 84MiB Also am DYNAMICIMAGE-Flag bei Bildern, die während der Laufzeit erstellt werden, scheints schon mal nicht zu liegen =/ Weiter habe ich folgendes Probiert: Das Bild nicht als AnimImage zu laden, sondern einfach mit LoadImage laden und mit Offset-Verschiebung und ViewPort das zeichnen eines Quasi-Frames zu erzwingen... Ergebnis: Code: [AUSKLAPPEN] OpenGL
DYNAMICIMAGE 31MiB FILTEREDIMAGE 31MiB MASKEDIMAGE 23MiB MIPMAPPEDIMAGE 31MiB D3D7 DYNAMICIMAGE 54MiB FILTEREDIMAGE 54MiB MASKEDIMAGE 56MiB MIPMAPPEDIMAGE 79MiB Während unter Direct3D7 keine enorme Verbesserung feststellbar ist, sieht man bei OpenGL - oder sehe ich und wage daraus zu schliessen -, dass offenbar durch das Extrahieren des Frames aus dem Pixmap eine Kopie des Bereichs erzeugt wird. Aber auch das entschuldigt noch keine 2MiB Sprünge. Denn angenommen, dass das 400x300 Pixmap in einer 512x512px, 32Bit/Pixel "Textur" untergebracht wird, gäbe das gerade mal 1MiB. Also ich denke, hier kann man - ohne etwas zu überstürzen - eine Optimierung verlangen. Der Workaround mit dem ViewPort scheint aber, dank D3D7 ![]() Zurück zu dir, Ava: Wie weit baut denn deine Gfx-Engine auf BMax auf? Also, welche Module hast du anangetastet gelassen? Liegt das evtl an der OpenGl- /DirectX-Implementierung in BMax oder ist das doch ein Problem, das tiefer begraben liegt? Wär mir zwar neu, dass alle D3D7- und OGL-Anwendungen das gleiche Verhalten aufweisen =/ @ Nicdel: Danke fürs testen! Ich hatte zuerst die Vermutung, dass das Problem von meiner Hardware verursacht wird, aber je mehr Leute mir zumindest ein ähnlich hohes Ergebnis bestätigen können, umso mehr verschwindet diese Vermutung. Jetzt bleibt immer noch die Frage, ob das Problem nun ich mit dem Code verursacht habe (habe ich irgendwas missachtet?), oder ob das in der Tat ein unschönes BMax-Feature ist. Gibts hierzu experten-Meinungen? ![]() Und ich wäre froh, wenn ich noch mehr Aussagen dazu bekäme ![]() mfG |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
ChristianK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Holzchopf hat Folgendes geschrieben: Und doppelter Speicherverbrauch find' ich sowieso grad mal ziemlich ungünstig
![]() Ohne dieses "Feature" würde dein oben genanntes Beispiel nicht funktionieren. Für jedes Bild bzw. jeden Frame wird eine Pixmap im Systemspeicher abgelegt. Erst wenn das Bild zum ersten mal gezeichnet wird, erstellt der entsprechende Max2D-Driver eine Kopie im Videospeicher durch OpenGL oder Direct3D (nicht nur bei DYNAMICIMAGE). Das hat den Vorteil, dass Graphics auch aufgerufen werden kann, nachdem ein Bild erstellt oder geladen wurde. Man kann dadurch auch den Max2D-Driver während der Laufzeit wechseln, ohne alle Bilder neu zu laden. Ohne die Kopie im Systemspeicher gingen die Daten jedes mal verloren. |
||
AdvanceLcd
Intel Core 2 Duo 3.2 GHz, 4 GB RAM, GeForce 8800 GTX | MacBook Pro 15,4″ Intel Core 2 Duo 2.4 GHz, 2 GB RAM, GeForce 8600M GT |
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kann man dieses Feature denn irgendwie ausschalten? Oder die im Systemspeicher abgelegten Kopien irgendwie freigeben? Aber wie schon gesagt, 2MiB für n 400x300 Pixmap sind ziemlich viel... | ||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
![]() |
BtbN |
![]() Antworten mit Zitat ![]() |
---|---|---|
Erstmal: Zuerst Graphics, dann das Image, nicht andersrum. Dann: Max2D hält 2 Pixmaps, quasi: Einmal die komplett-Pixmap, und dann einmal jede zerschnittene Einzel-Pixmap. Daher der genau doppelte verbrauch.
Zudem kommen noch diverse vorgeladene sachen von Modulen, vorallem da du kein Framework setzt. Ein Framework auf das nötigste sollte den Ram-Verbrauch schonmal senken. Die Images auf der GraKa(Texturen) zählen übrigens nicht zum Ram-Verbrauch. Zudem muss man beachten, dass BMax intern die pixmap auf die nächste quadratzahl hochskaliert(Also in dem fall hier 512x512 Pixel) Zu Mipmapped-Image: Dass das mehr verbraucht, ist logisch: Es wird das anfangsbild genommen, gespeichert, auf die halbe auflösung runterskaliert, gespeichert, skaliert, ... bis es nurnoch 1x1 groß ist. So können kleinere bilder schneller gezeichnet und rotationen sauberer dargestellt werden. |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke für die Antwort, aber bis auf "zuerst Graphics, dann Images", sagst du mir leider nichts neues.
Wie du ja im ersten Post gelesen hast, machts keinen unterschied, ob ich ein Framework setze oder nicht - und wenn, obs GlMax2D ist oder D3D7Max2D ![]() Das mit dem zuerst Graphics und dann Images hab ich auch glatt probiert - brachte aber nix ![]() Und auch - wie auch schon bereits erwähnt - wenn die Images in 512x512px Texturen untergebracht werden, kann ich mir die 2MiB Sprünge nicht erklären... ... erst recht nicht, wenn du sagst, dass Texturen nicht zum Ram-Verbrauch zählen ![]() ![]() Das mit Mipmapped-Image war mir auch noch irgendwoher logisch (wahrscheinlich, weils schon in den Doks steht *hust*), aber wenn man irgendwas recherchieren will, sollte man auch nix auslassen - gut, ich gebs zu, ich habe nicht alle Flag-Kombinationen ausprobiert (höchstens noch alle Flags gleichzeitig setzen, aber noch höher hab ich die Ram-Auslastung nicht hingebracht... Also, mal ein anderer Ansatz (da du ja eines auch Bestätigst - und mit deinen, Avas und ChristianKs Argumenten glaube ich das gerne): Wenn BMax zwei kopien hält - und eine davon im Graka-Speicher, der nicht zur Ram-Auslastung zählt - wie kann dann ein 512x512px Pixmap 2MiB zusätzlichen Speicher verursachen? Ich könnte mich jetzt ja durch den Modul-Urwald von BMax kämpfen und schauen, ob evtl DrawImage eine Kopie erstellt und die Methode zum zeichnen des Pixmaps noch eine weitere - aber ich weiss nichtmal, ob ich das herausfände ![]() Ist ja offenbar ein BMax-Only-Feature, also sollte es doch irgendwie möglich sein, das zu umgehen? mfG |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
![]() |
BtbN |
![]() Antworten mit Zitat ![]() |
---|---|---|
DrawImage kopiert garnichts, es aktiviert nur die Textur und zeichnet ein quadrat. Der zusätzliche ram-Verbrauch muss von anderen Modul-Interna kommen.
Hast du schonmal versucht, ein GC-Collect mit in die Hauptschleife einzubauen, und deine nicht mehr benutzten Pixmap-Variablen und Image-Variablen = Null zu setzen, nachdem du sie benutzt hast? |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Oh, tschuldigung, mein Fehler ![]() ![]() Mit Pixmap = Null hat leider auch nix geändert =( |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
![]() |
mahe |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also wenn Du Deine Rechnung aus dem ersten Code anpasst kommst Du auf 40 MB Verbrauch. Der Rest zu den 57 MB kann man sich dann durchaus mit Modulen, Rundherum usw. erklären.
Code: [AUSKLAPPEN] 400x300 px = 120000 px
x 4 Byte/px = 480000 Byte x 20 (Frames) = 9600000 Byte = 9375 KiB = 9.2 MiB angepasst: Code: [AUSKLAPPEN] 512x512 px = 262144 px ;So groß muss das Bild wirklich sein
x 4 Byte/px = 1048576 Byte x 20 (Frames) = 20971520 Byte = 20480 KiB = 20 MB * 2 = 40 MB ;Nochmal mal 2 weil es laut BtbN 2x vorgehalten wird Auch die 2-MB-Sprünge sollten jetzt erklärbar sein. |
||
ʇɹǝıdɯnɹɹoʞ ɹnʇɐuƃıs - ǝpoɥʇǝɯ-ɹoɹɹıɯ ɹǝp uı ,ɹoɹɹǝ, |
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zählen denn nun die Kopien, die ja auf der GraKa gespeichert werden, zum Ram-Verbrauch oder nicht? Oder werden die gar nicht auf der GraKa gespeichert? Dann gings auf... Also, mal davon abgesehen, dass ich ganz pingelig bin und die zusätzlichen 17MiB immer noch nicht akzeptiere ![]() |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
![]() |
mahe |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Kopie auf der GraKa ist da nicht eingerechnet. Dort müsste es spätestens beim Zeichnen nochmals hinkopiert werden. Ich vermute aber mal ganz stark, dass es immer auch im RAM liegen muss weil der Platz auf der GraKa ja durchaus sehr begrenzt sein kann und dann da öfter was überschrieben werden muss.
Die zusätzlichen 17 MB könntest Du möglicherweise reduzieren wenn Du 'Framework' und 'Import' verwendest und so nur die wirklich benötigten Module lädst. |
||
ʇɹǝıdɯnɹɹoʞ ɹnʇɐuƃıs - ǝpoɥʇǝɯ-ɹoɹɹıɯ ɹǝp uı ,ɹoɹɹǝ, |
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wie schon gesagt, auch wenn ich Framework BRL.GlMax2D einbinde (sonst keine Module, läuft ja so), siehts mit der Ram-Auslastung genau gleich aus.
Heisst dass aber, Max2D macht 2 Kopien? Eine nochmal im Ram und eine auf dem GraKa-Speicher? |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
![]() |
BtbN |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ein Image liegt IMMER als Textur im Ram der GraKa, sobald man es läd. Zusätzlich hält BMax in einem Image aber auch eine Pixmap des bildes im Ram, um es bei veränderungen neu hochladen zu können.
Dabei existiert eine Pixmap pro Frame, und u.U. nochmal eine Gesammt-Pixmap mit allen Frames aneinander. Und nein, es liegt wirklich IMMER im VRam, wenn dort voll ist, ist sense mit dem Programm. Allerhöchstens hält der Treiber das bild nochmal im Ram, was ich aber wiederrum für sehr unwahrscheinlich halte. Und was im VRam liegt, zählt NICHT zum normalen Ram-Verbrauch. |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ok, sehr ausführlich, danke =)
Das heisst, wenn man Frames auch immer schön in ein 2er-Potenz-Quadrat-Raster (verständlich? sollte schon...) bringt und voll ausnützt, kann man u.U. schon was sparen? Dank Echtzeit-Transformationen kann man ja in Extremfällen ein Bild auch etwas kleiner speichern und hoch skalieren... Und dann gibt's ja noch die zerschnippsel-Lösung*, die zumindest bei mir unter OGL schon ziemlich was bringt ![]() edit: *Per Viewport, wohlgemerkt ![]() Ich kann's momentan leider nicht testen, aber erzeugen 3D-Module (minib3d und co) auch Texturkopien? Weiss das grad jemand? *liebindierundeguck* ![]() |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group