Bereiche
News
Rewind
Tipps & Berichte
Forum
Galerie
Journals
Events
Umfragen
Themenwoche
Kleinanzeigen
Interaktiv
Anmelden
Registrierung
Zu allen empfangenen Nachrichten
Suche...
Zur erweiterten Suche
Push-Nachrichten von MacTechNews.de
Würden Sie gerne aktuelle Nachrichten aus der Apple-Welt direkt über Push-Nachrichten erhalten?
Forum
>
Entwickler
>
Speicherleck (CGImageRef)
Speicherleck (CGImageRef)
Christoph_M
30.04.12
00:26
Hallo zusammen,
ich habe ein Problem und zwar läuft meine Cocoa Mac Applikation durch eine Schleife und verbraucht in jedem Durchgang zusätzliche 18MB Ram, was dazu führt dass auch 12GB irgendwann voll sind und dann das Paging los geht.
Der Code sieht so aus:
while([[startStopButton title] isEqualToString:@"Stop"]) {
CGImageRef screenshot = CGDisplayCreateImage(kCGDirectMainDisplay);
NSBitmapImageRep *bitmapRep = [NSBitmapImageRep alloc];
bitmapRep = [bitmapRep initWithCGImage:screenshot];
screenHeight = (int)bitmapRep.pixelsHigh;
heightStep = screenHeight/7; // 14 Schritte
screenWidth = (int)bitmapRep.pixelsWide;
widthStep = screenWidth/100*widthPercentage;
...
}
Das Problem ist die Zeile:
CGImageRef screenshot = CGDisplayCreateImage(kCGDirectMainDisplay);
Wenn ich diese aus der Schleife rausnehme und nur einmal ausführe und der Rest dann darauf zugreift bleibt die RAM-Belegung konstant bei ca. 80MB.
Nur was kann ich machen?
Wenn ich free(screenshot); mache, dann ist es entweder zu früh und es gibt Laufzeitfehler oder der Pointer existiert schon gar nicht mehr (Garage Collection ist aktiviert).
Ich hab bestimmt irgendwo einen Denkfehler drin, bin für jeden Stups in die richtige Richtung dankbar!
Grüße,
Christoph
Hilfreich?
0
Kommentare
Duck Dodgers
30.04.12
08:44
Hast du die Doku gelesen?
http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html
The caller is responsible for releasing the image created by calling CGImageRelease.
P.S: War gleich der zweite Link bei Google
Hilfreich?
0
Marcel Bresink
30.04.12
10:16
Garbage Collection funktioniert standardmäßig nur für reine Cocoa-Objective-C-Programmteile. Wenn man C-Schnittstellen verwendet (z.B. malloc oder CGImage-Funktionen), muss man sich bezüglich dieser Funktionen trotzdem "manuell" um die Speicherverwaltung kümmern.
Wenn in Apples API in einem Funktionsnamen die Bezeichnungen "Create" oder "Copy" auftauchen, wird immer Speicher reserviert, der vom Aufrufer wieder freigegeben werden muss. Dieser Speicher wird niemals mit "free" freigegeben, sondern immer nur mit einer ...Release-Funktion der entsprechenden Bibliothek, hier in diesem Fall also mit "CGImageRelease(screenshot)".
Für neue Programme sollte man übrigens Garbage Collection nicht mehr verwenden. GC wurde (zur optionalen Nutzung) in Mac OS X 10.5 eingeführt, hat sich aber mehr oder weniger als gescheitertes Experiment erwiesen und wird von Apple nicht mehr weiterentwickelt.
Hilfreich?
0
Christoph_M
30.04.12
10:34
Danke euch beiden!
Habs direkt ausprobiert und es funktioniert!
Was mich allerdings wunder: ich erstelle das Screenshot doch jedes mal in die selbe Variable Screenshot. Müsste dadurch nicht der allokierte Speicherbereich überschrieben werden? Wenn nicht, wo landet dann das neue Screenshot?
Danke und Grüße,
Christoph
Hilfreich?
0
ExMacRabbitPro
30.04.12
11:28
Christoph_M
Danke euch beiden!
Habs direkt ausprobiert und es funktioniert!
Was mich allerdings wunder: ich erstelle das Screenshot doch jedes mal in die selbe Variable Screenshot. Müsste dadurch nicht der allokierte Speicherbereich überschrieben werden? Wenn nicht, wo landet dann das neue Screenshot?
Danke und Grüße,
Christoph
Diese Funktion: CGDisplayCreateImage fordert bei jedem Aufruf neuen Speicher von System an - unabhängig davon was zuvor geschah oder in welche Zeiger-Variable die zurückgelieferte Referenz gespeichert wird.
Hilfreich?
0
Marcel Bresink
30.04.12
12:17
Was mich allerdings wunder: ich erstelle das Screenshot doch jedes mal in die selbe Variable Screenshot.
Nicht wirklich. Die Variable screenshot ist vom Typ CGImageRef, also nur eine
Referenz
auf ein Bild, nicht das Bild selbst.
In Wirklichkeit ist das ein Zeiger auf eine Datenstruktur, die wiederum Zeiger auf Speicherbereiche enthält, die das Bild enthalten. Diese Speicherbereiche werden bei jedem "Create" immer wieder neu vom System abgebucht.
Nur wenn Garbage Collection auch für die C-Funktionen aktiv wäre, dann würde die Laufzeitumgebung erkennen, dass durch das Überschreiben der Referenz auch die referierte Datenstruktur freigegeben werden müsste. Wie gesagt wird Garbage Collection aber hier standardmäßig nicht verwendet.
Hilfreich?
0
MacMark
30.04.12
13:51
Doku in Xcode und Dev pages Apple:
CGDisplayCreateImage
Returns an image containing the contents of the specified display.
CGImageRef CGDisplayCreateImage(
CGDirectDisplayID displayID
);
Parameters
display
The identifier of the display for which an image is being created.
Return Value
An image containing the contents of the specified display. If the display ID is invalid, the return value is NULL.
The caller is responsible for releasing the image created by calling CGImageRelease.
Availability
Available in Mac OS X v10.6 and later.
Declared In
CGDirectDisplay.h
„@macmark_de“
Hilfreich?
0
Duck Dodgers
30.04.12
14:08
Lesen ist nicht gerade deine Stärke *sick*
Hilfreich?
0
Christoph_M
30.04.12
15:58
Danke nochmal allen für die zahlreichen Antworten
Das Releasen funktioniert wunderbar, mir war nur nicht bewusst, dass sich der Speichbereich nach jedem Schleifendurchlauf verändert und damit das alte Bild im Speicher zurückbleibt. Danke Marcel für die Erklärung.
Duck Dodgers
*sick*
Hilfreich?
0
MacMark
30.04.12
20:07
Dir fehlt elementares Grundlagenwissen zur Objective-C Programmierung. Kauf Dir ein Buch, sonst wird das nichts. Da steht sowas im Einführungskapitel, Homer.
Und Programmierer, die a) bei Problemen Google fragen, und b) eine Zeile ohne Kontext posten, kann man ebenso knicken. Ich schaue dich an, Duck.
„@macmark_de“
Hilfreich?
0
Kommentieren
Diese Diskussion ist bereits mehr als 3 Monate alt und kann daher nicht mehr kommentiert werden.
2 TByte für 259 US-Dollar: Erste Upgrade-SSDs f...
Apple veröffentlicht iOS 18.2, iPadOS 18.2 und ...
Weitere Berichte zur neuen Kamera des iPhone 17...
Vor 18 Jahren: iPhone, Apple TV und "Apple Inc."
iPod-Vater Tony Fadell wollte Sonos kaufen – St...
Gurman zum Release des neuen Apple TV, HomePods...
Thunderbolt 5 am M4-Mac: Erstes Dock hinterläss...
Mac OS X: 25 Jahre Aqua, 25 Jahre Dock