• Willkommen im Geoclub - dem größten deutschsprachigen Geocaching-Forum. Registriere dich kostenlos, um alle Inhalte zu sehen und neue Beiträge zu erstellen.

[Dev?] OutOfMemoryError

Kalli

Geowizard
Nachdem einige User (bei der Win-Version) von Speicherproblemen berichtet haben und es sich um eine Größe von ca. 12 MB handelt, ist mir eingefallen, dass beim Build folgenden Kommandozeilenparameter in der .jnf-Datei eingestellt wird: /Xmx 12M

Hierdurch wird der maximale Heap-Space auf 12 MB begrenzt, müsste für alle Versionen gelten, auch für die .jar.

Reingekommen ist der Parameter, weil es Probleme gab, nachdem kalibrierte Karten geladen wurden. Pfeffer hatte etwas geforscht und war hier fündig geworden.

Primär war das gedacht, damit der CW auf dem PDA keine Speicherprobleme bekommt. Hört sich so an, als ob wir jetzt Probleme auf dem PC bekommen, wo Speicher an sich kein Problem ist. Ich habe das Gefühl, wir haben jetzt die Wahl zwischen Pest und Cholera:
- Der Parameter wird rausgenommen, dann gibts Probleme mit den Karten auf dem PDA, dafür keine mit der Win-Version
- Für den Build-Prozess werden unterschiedliche .jnf genutzt, also eine separate für die PDA-Version.

Any Ideas?
 

Bilbowolf

Geowizard
Verschiedene Builds...

habe aber das Problem auch beim Entwickeln ohne dem /Xms.

Es liegt am Cacheholder Object iVm der cacheDB. Der GC hat da nix zum collecten und so wächst der Speicherbedarf konstant an. Eine Lösung habe ich bisher nicht gefunden. Ich denke ich muss beim Spider die cacheDB umgehen :?
 

pfeffer

Geowizard
nein, die cacheDB umgehen ist keine (vernünftige) Lösung. Habe mir das grad mal etwas angeschaut:
Wir brauchen einfach eine Funktion in der cacheholder.java "freeCacheDetails()", die alle Daten, die nicht in der index.xml stehen durch =null setzen für die GarbageCollection frei gibt. Sie müsste dann in der SipderGC und OCXMLImporter (und GPX-Importer?) aufgerufen werden nachdem die Details auf Festplatte geschrieben wurden und bevor der lokale Cacheholder (ch in OCXMLImporter und in SpiderGC) mit einem neuen CacheHolder-Objekt überschreiben wird.
Vermutlich ist es sinnvoll diese Methode direkt in cacheholder.saveCacheDetails(boolean clearDetailsAfterWrite) aufzurufen.

Wenn ich das richtig sehe, wird diese Funktion eigentlich auch beim Download von Opencaching und vermutlich ebenso beim GPX-Import gebraucht. Damit müsste sich das Problem doch einfach lösen lassen, oder?

Schöne Grüße,
Pfeffer.
 

salzkammergut

Geomaster
Bilbowolf schrieb:
Es liegt am Cacheholder Object iVm der cacheDB. Der GC hat da nix zum collecten und so wächst der Speicherbedarf konstant an. Eine Lösung habe ich bisher nicht gefunden.

Tschuldige, aber da stehe ich auf der Leitung. Warum sollen die CacheHolder Objekte ein Memoryleak verursachen? Beim Spidern werden die CacheHolder Objekte ja notgedrungen erzeugt, weil für jeden neu gespiderten Cache ein solches Objekt angelegt wird (einschliesslich Addis). Diese Objekte können nicht wieder freigegeben werden sondern belegen solange Speicher, bis ein neues Profil geöffnet wird. Irgendwann muss da der Speicher ausgehen.

Ein Leak gibt es nach meinem Verständnis dann, wenn ein Objekt zwar vom Programm her freigeben wurde (wie z.B. im Spider die diversen lokalen RegExe und Extractoren), aber vom Speicherallokator nicht wieder verwendet wird. Dann bleibt dieser Speicher dauerhaft "gesperrt", und wird eventuell zu einem Speichermangel führen.

Ich denke ich muss beim Spider die cacheDB umgehen
Wie soll das gehen? Die neu gespiderten Caches müssen ja in die CacheDB eingetragen werden. Ausserdem ist die CacheDB ja nur eine Liste von Zeigern auf CacheHolder Objekte und braucht daher nicht sehr viel Speicherplatz (Wobei interessant ist, daß ein Vector seine Größe in 2er Potenzen ändert, d.h. wenn kein Platz mehr ist für ein neues Objekt, wird ein neuer Speicher zugewiesen mit der doppelten Größe des alten Vectors und der alte Vector dorthin kopiert).

Kann der Speicherüberlauf im Spider durch zuviele Logs verursacht werden (da sollte ein in den Präferenzen einstellbares Limit her wie schon wo anders angeregt wurde)?

Auch sind im CacheHolder einige Eigenschaften als "String", die man auch als Zahl oder Boolean speichern kann (z.B. dirty, type, hard, terrain usw.) was einiges an Speicher spart. Das sollte aber bei nur 200 Caches kein Problem sein.

Ein (etwas verwirrter)
salzkammergut
 

pfeffer

Geowizard
@Salzkammergut: Wenn ich BilboWolf richtig verstanden habe, dann wird das Problem dadurch verursacht, dass die CacheDB Zeiger auf alle CacheHolder hält, die beim Spidern und Download von Opencaching (und vermutlich auch beim GPX-Import) die vollständigen Daten der Caches, inklusive der Beschreibungen, Logs usw. enthalten. Allerdings werden diese Daten nie wieder verwendet, sie werden bei Bedarf immer neu von der Festplatte gelesen. Deswegen mein Vorschlag, diese Daten nach dem Schreiben auf die Festplatte aus dem Speicher zu entfernen.

Gruß,
Pfeffer.
 

salzkammergut

Geomaster
@Pfeffer: Deine Idee mit "freeCacheDetails" finde ich gut, das ist einfach und kann schnell implementiert werden. Eigentlich müßte diese Funktion dann auch aufgerufen werden, wenn in der Listenansicht ein neuer Cache angezeigt wird (in MainTab.java). Denn auch da werden die zusätzlichen Daten aus der Cachedatei zwar gelesen aber nie wieder freigegeben.
 

Bilbowolf

Geowizard
Das, was ihr denkt habe ich auch gedacht und sowas eingetragen (in CacheHolder):

Code:
public void freeMEM(){
		LongDescription = EMPTY;
		LastUpdate = EMPTY;
		Hints = EMPTY;
		CacheLogs.clear();
		CacheNotes = EMPTY;
		Images.clear();
		ImagesText.clear();
		LogImages.clear();
		LogImagesText.clear();
		UserImages.clear();
		UserImagesText.clear();
		attributes.clear();
		CacheIcons.clear();
		Bugs = EMPTY;
		URL = EMPTY;
		ocCacheID = EMPTY;
	}

Hat aber, warum auch immer nichts gebracht :(
 
OP
Kalli

Kalli

Geowizard
Gleiches wie oben beschrieben, gilt auch für einige Exporter. Zum einen für die, wo die Beschreibung drin ist (z.B. GPX oder HTML), zum anderen für die, die eine URL verwenden.

Wenn ich Bilbowolfs Ansatz richtig verstehe, soll es in "kritischen" Routinen nur ein CacheHolder Objekt geben, welches die Beschreibungen und die Logs enthält, dieses wird wiederverwendet. Wir hätten dann also die Daten, die in der index.xml landen, in der CacheDB, zusätzlich ein lokales Objekt, welches neben den Daten der index.xml auch die Beschreibungen und Logs enthält. Beim Import wird es, nachdem die Daten vollständig sind, weggesichert und dann gelöscht. Gleiches könnte man bei den Exportern machen, die die Cachedetails benötigen (kann man zentral in Exporter.java lösen). Der OCXML-Importer nimmt eine Sonderrolle ein, da man dort die Daten eines Caches nie komplett bekommt, dafür muss der (außer bei der Initialbefüllung) nicht mit so vielen Daten umgehen.

Allerdings macht mir Bilbowolfs Versuch nicht so viel Hoffnung, dass es funktioniert.
 

pfeffer

Geowizard
hmm... ähnliche Probleme hatte ich auch mal bei der MovingMap :-(

Ich habe da an manchen Stellen Vm.gc() eingebaut, vielleicht hilft das?

Schöne Grüße,
Pfeffer.
 

Bilbowolf

Geowizard
Habe ich, hat nichts gebracht.

Ich habe aber soeben die 647 eingecheckt. Und da ist das Problem gelöst :D Ich habe in der Tat die cacheDB umschifft (nur für den spider, ansonsten ist sie natürlich noch aktuell).

Ich muss jetzt noch die addiwpt einbinden (was ich meine seht ihr im code) und warum auch immer, gc spinnt aktuell mit der rückgabe von found / not found. Habe aber auch dafür eine Lösung, die ich heute noch einbauen werde. Ist heute Abend fertig und somit werde ich die RC final freigeben.

Somit sollte für die 0.9n für Freitag nichts im Wege stehen. Vorher MUSS das Handbuch fertig sein.
 
A

Anonymous

Guest
Da ein sorry von mir - da ich in urlaub sein werd kann ich mit dem handbuch leider kaum helfen...
 

dewildt

Geomaster
Christian und die Wutze schrieb:
Hat außer mir noch jemand das OutOfMemoryError-Problem beim GPX Import in der Windows Version (RC 656)?
Vermutlich, fällt nur niemanden auf :lol:
Ich habe ein ähnliches Problem beim GPX-Export von einige (etwa 500) Caches.
Sammy Raider meinte dazu
... dieses Problem hatte ich auch, versuch's mal mit der Java-Version, damit konnte ich ohne Probleme 800 Caches exportieren!
Sein Tipp habe ich zwar nicht getestet, rate ab mal wie meine Empfehlung für dein Import-Problem aussieht :wink:

Wird wohl ein EWE-Problem sein.

Edit: Im EWE-Forum steht folgendes
it will hang quite often with "java/lang/OutOfMemoryError Used:4150368, Need: 4584804".
...
You can use the -Xmx parameter to specify the maximum amount of memory needed by your application. For example: "-Xmx 8M"
Vielleicht hilft das.

Gruss,
Daniel
 
Oben