Bild aus Speicher entfernen ?

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Cardonic

Betreff: Bild aus Speicher entfernen ?

BeitragFr, Jun 02, 2006 14:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi

Kann mir jemand sagen, wie ich in BlitzMax ein Bild aus dem Speicher entferne (wie mit FreeImage() in BlitzBasic) ?
Ich hab schon etliche Varianten durchgespielt, aber ich bin noch nicht auf eine funktionierende Lösung gekommen.

mfg Cardonic

PS : Ja, ich habe die Bordsuche benutzt und auch einen passenden Thread dazu gefunden. Ich bin aus diesem Thread leider nicht sehr schlau geworden Rolling Eyes
If you should go skating on the thin ice of modern life, dragging behind you the silent reproach of a million tear-stained eyes, don't be surprised when a crack in the ice appears under your feet.

d-bug

BeitragFr, Jun 02, 2006 15:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
DeinImage = Null


Den Rest macht der GarbageCollector von alleine.

cheers

Cardonic

BeitragFr, Jun 02, 2006 16:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi

Vielen Dank für deine Antwort.

Ich hab aber diesbezüglich noch eine kleine Frage: Ist es normal, dass im Task-Manager die angezeigte Speicherauslastung des betreffenden Prozesses nicht zurückgeht, nachdem man ein Bild aus dem Speicher gelöscht hat ?

mfg Cardonic
If you should go skating on the thin ice of modern life, dragging behind you the silent reproach of a million tear-stained eyes, don't be surprised when a crack in the ice appears under your feet.

Farbfinsternis

BeitragFr, Jun 02, 2006 16:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Lies die BILD oder den Taskmanager ... der Wahrheitsgehalt beider Publikationen geht gegen Null.
Farbfinsternis.tv

rema

BeitragFr, Jun 02, 2006 17:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Wäre immer wieder schön zu sehen wenn man gleich noch den Quellcode postet...

Grafiken werden normalerweise in dem Arbeitsspeicher von der Grafikkarte geladen. Ausser du gibts beim laden explizit an, dass dieser im Ram bleiben soll. Und auch Pixmaps werden im Ram gehalten.

Jolinah

BeitragFr, Jun 02, 2006 19:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Der GarbageCollector funktioniert aber offenbar auch noch nicht ganz so toll..

Z.B. wenn man einen eigenen Type erstellt und davon ein Objekt macht, dieses dann wieder auf Null setzt und das Programm beendet, dann wird entweder der Destruktor nicht aufgerufen, oder der Speicher wird tatsächlich nicht freigegeben...

Ich wollte den Destruktor bei einem Type der manuell Speicher reserviert dazu nutzen diesen Speicher automatisch wieder freizugeben, ohne dass man dazu eine Methode aufrufen muss. Aber der Destruktor wurde beim Programmende gar nicht aufgerufen, obwohl ich die Variable vor dem Ende auf Null gesetzt hatte.

Code: [AUSKLAPPEN]
Type Test

   Field mem:Byte Ptr

   Method New()
      mem = MemAlloc(128)
   End Method
   
   Method Delete()
      DebugStop
      If mem <> Null Then MemFree(mem)
   End Method
End Type

Local t:Test = New Test

t = Null

'GCCollect()
End


Wenn man das als Debug kompiliert und ausführt kommt man nie in den Debugger, das heisst Delete() wird gar nicht ausgeführt. Mit GCCollect() am Ende gehts.

Bei WinXP wird wahrscheinlich trotzdem am Ende alles aufgeräumt, aber wie siehts wohl mit Win98 etc. aus?

rema

BeitragFr, Jun 02, 2006 21:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Delete und New sind nur reservierte Schlüsselwörter. New wird immer ausgeführt. Delete wird nie ausgeführt, ausser man springt diesen selber an.

GCCollect() setzt man am besten innerhalb der Programmschleife und ruft ihn nicht gleich bei jedem Löschung auf, sonst lahmt das Programm. GCCollect() gibt nur den Speicher frei von Variabeln die auf NULL gesetzt sind.

Ist ein wenig gewöhnungsbedürftig, aber die meisten sind zufrieden, da GCCollect() gezielt angewendet werden kann und zbsp nicht bei RealTime Sachen dazwischen funkt.

Aber du kannst mit GCSetMode(x) folgende Dinge festsetzen:

[qoute]mode can be one of the following:
1 : automatic GC - memory will be automatically garbage collected
2 : manual GC - no memory will be collected until a call to GCCollect is made
The default GC mode is automatic GC.
[/quote]


Sont funktionierts bei mir auf dem Mac.

Code: [AUSKLAPPEN]

Type Test

   Field mem:Byte Ptr
   Field test:Int[1000000]

   Method New()
      mem = MemAlloc(1)
   End Method
   
   Method Delete()
      DebugStop
      If mem <> Null Then MemFree(mem)
   End Method
End Type


Print "1) "+ GCMemAlloced()

Local t:Test = New Test

Print "2) "+ GCMemAlloced()

t = Null

Print "3) "+ GCMemAlloced()

GCCollect()

Print "4) "+ GCMemAlloced()

End
  • Zuletzt bearbeitet von rema am Fr, Jun 02, 2006 22:05, insgesamt 3-mal bearbeitet

Jolinah

BeitragFr, Jun 02, 2006 21:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, mit dem GCCollect() schon. Aber ohne räumt er bei mir am Ende nicht auf, bzw. führt den Destruktor nicht aus, obwohl der GC Modus auf automatisch gestellt ist...

rema

BeitragFr, Jun 02, 2006 22:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry, habe oben noch eine Erklärung hinzu gefügt... ^^

Jolinah

BeitragFr, Jun 02, 2006 23:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Delete wird schon ausgeführt Wink Nämlich dann wenn das Objekt zerstört wird. Sobald ich GCCollect() aufrufe wird auch Delete von dem Objekt automatisch ausgeführt (noch bevor es zerstört ist natürlich).

Der automatische GarbageCollector funktioniert auch ansonsten ganz gut, also zum Beispiel in der Hauptschleife, oder in einem anderen Scope (If, For usw.), werden automatisch alle Null Variablen eingesammelt, und auch bei denen wird jeweils die Delete Methode bzw. der Destruktor ausgeführt (auch ohne das GCCollect()).

Mir ging es nur darum, dass der automatische GarbageCollector ganz am Ende des Programms offensichtlich nicht ausgeführt wird. Naja, ist auch nicht so schlimm, ich wollte es halt nur erwähnen. Aber ich persönlich werde jetzt wahrscheinlich immer am Ende noch ein GCCollect() hinsetzen...

rema

BeitragSa, Jun 03, 2006 0:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Du kannst ja mit OnEnd() dies automatisieren...

Code: [AUSKLAPPEN]

OnEnd( jetztistschluss() )

....

Function jetztistschluss()
     GCCollect()
End Function

Jolinah

BeitragSa, Jun 03, 2006 18:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Schon klar Smile aber der Punkt ist doch dass es das automatisch machen sollte, ohne dass ich da eine zusätzliche Zeile Code schreiben muss. Denn der GarbageCollector ist ja auf automatisch gestellt, also soll er es auch automatisch machen...

Sprich:
Code: [AUSKLAPPEN]
Local o:Test = new Test
o = Null
End

rema

BeitragSa, Jun 03, 2006 18:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist so eine Ansichtssache. Der Speicher wird bei Programmende schon frei gegeben, nur ist dies Betriebssystemabhängig. Zbsp Linux oder MacOS: als Umsteiger von Windows ist man es sich nicht gewohnt dass der Speicher so schnell voll läuft. Aber das hat auch seinen guten Grund, wie dies auch bei BlitzMax der Fall ist. Die Speicherfreigabe braucht Systemresourcen. Darum sollte man den Speicher erst freigeben wenn auch Speicher von anderen Resourcen gebraucht wird. Zudem hat diese Methode auch seinen Vorteil. Wenn ein Programm wiederholt aufstartet wird (zbsp Firefox), so ist dieser im Speicher schon vorhanden, und muss nicht erst wieder von der lahmen Festplatte geladen werden.

Also würde ich nicht auf so ein paar Bytes rumreiten. Fülle mal deinen Speicher und schau selber, was dein Betriebssystem macht...

Blacal

BeitragSa, Jun 03, 2006 19:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Servus

Warum der Destruktor am Ende des Programms net aufgerufen wird?
ganz einfach:
Woher soll denn der GarbageCollector wissen, in welcher Reihenfolge er die Destruktoren aufrufen soll?
Denn es könnte passieren, dass du im Destruktor ein Objekt verwenden willst, welches der GarbageCollector bereits zerstört hat.
Daher wird ganz einfach der komplette Speicher (Oder in Linux, MacOS nur der Stack, so wie ich dass da weiter oben verstanden hab) freigegeben.
Somit brauchst du am Ende des Programms nicht GCCollect aufrufen, da der Speicher freigegeben wird.

Du musst nur verbindungen nach außen Schließen, denn wenn du z. B. noch eine Netzwerkverbindung offen hast, bleibt diese für den anderen Rechner nocht offen.

Mfg Blacal

Jolinah

BeitragSa, Jun 03, 2006 20:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, danke Wink Wenn das der Fall ist, bin ich zufrieden. Ich hoffe Speicher den man manuell reserviert hatte, wird aber vom Betriebssystem ebfenfalls bei Programmende freigegeben. Denn aus diesem Grund wollte ich ja eigentlich den Destruktor. So lange das Programm läuft funktioniert das mit dem Destruktor ja auch ganz gut und der Speicher wird während das Programm läuft freigegeben, wenn auch das Objekt freigegeben wird Smile

Blacal

BeitragSa, Jun 03, 2006 20:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Das kannst du ganz einfach rausfinden
lass mal dein Programm so 200 MB Speicher reservieren, und dann beende es Wink

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group