[JAVA] Runtime geheugen klopt niet

Pagina: 1
Acties:

  • Gonadan
  • Registratie: Februari 2004
  • Nu online

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Ik heb een programmaatje dat een heleboel strings uit een heel groot bestand haalt via een native methode.

Ik print periodiek het geheugen uit om te controleren of hij niet te veel gebruikt.
Java:
1
2
3
Runtime.getRuntime().totalMemory() geeft 2031616
Runtime.getRuntime().freeMemory() geeft 1878936
Runtime.getRuntime().maxMemory() geeft 66650112


de freeMemory() schommelt natuurlijk een beetje
wat is het probleem denk je dan, nou als ik naar de windows taskmanager kijk dan giert het geheugengebruik van java.exe naar zo'n 580MB en dan krijg ik zo'n lieve
Java:
1
2
3
4
5
6
7
8
9
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x100012cb, pid=1084, tid=804
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode, sharing)
# Problematic frame:
# C  [HelloWorld.dll+0x12cb]
#


Heeft iemand een idee hoe dat mogelijk is? Heb ik een grandioos lekje ergens ofzo :?

Look for the signal in your life, not the noise.

Canon R6 | RF 24-70 f/2.8 L | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Verwijderd

Welke native methode gebruik je dan en waarom gebruik je die als er 'tig classes zijn in rt.jar voor I/O ?

Ik denk dat je strings geïnternd worden. Ze komen dan niet in de heap die door de garbage collector wordt uitgemest van tijd tot tijd, maar in de native heap die de JVM voor interne bookkeeping houdt. Het is een truukje om de performance wat op te krikken dewelke oorspronkelijk uit de Lisp wereld kwam.

Het kan natuurlijk ook iets anders zijn, zeker als je JNI zit te gebruiken, waarbij je maar al te makkelijk vergissingen kan maken wat betreft geheugenbeheer. "100% pure Java" is niet enkel een loze marketingkreet van Sun.

  • Gonadan
  • Registratie: Februari 2004
  • Nu online

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Verwijderd schreef op woensdag 08 maart 2006 @ 15:49:
Welke native methode gebruik je dan en waarom gebruik je die als er 'tig classes zijn in rt.jar voor I/O ?

Ik denk dat je strings geïnternd worden. Ze komen dan niet in de heap die door de garbage collector wordt uitgemest van tijd tot tijd, maar in de native heap die de JVM voor interne bookkeeping houdt. Het is een truukje om de performance wat op te krikken dewelke oorspronkelijk uit de Lisp wereld kwam.

Het kan natuurlijk ook iets anders zijn, zeker als je JNI zit te gebruiken, waarbij je maar al te makkelijk vergissingen kan maken wat betreft geheugenbeheer. "100% pure Java" is niet enkel een loze marketingkreet van Sun.
Ik gebruik een native methode die aan de hand van een selectiesleutel een String array retourneert
Ik lees namelijk uit een database file waar een DLL bij zit. En om met Java een DLL aan te roepen moest ik eerst een native methode schrijven die hem aanroept.

Is er geen manier om uit te vinden waar dat geheugen blijft? Ik heb namelijk het vermoeden dat de native methoden ergens iets open laten, ook al heb ik geprobeerd steeds alles weer vrij te geven.
Nu weet ik trouwens ook niet of de GC wel naar die native methoden kijkt of alleen de java meuk weghaalt. :?

Edit: wat ik ook erg verdacht vind is dat hij steeds exact op dezelfde plaats crasht.

[ Voor 5% gewijzigd door Gonadan op 08-03-2006 15:56 ]

Look for the signal in your life, not the noise.

Canon R6 | RF 24-70 f/2.8 L | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


  • Gonadan
  • Registratie: Februari 2004
  • Nu online

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Ik heb weer wat verder zitten prutsen. En ik heb ontdekt dat als ik die native functie niet aanroep dat het geheugen normaal blijft.
Het geheugen wat de native functie heeft gebruikt wordt dus niet meer vrijgegeven. Is er een manier om dat handmatig te doen? Ik kan wel in de native functie zelf alle pointers gaan vrijgeven maar de returnwaarde kan ik sowieso niet vrijgeven omdat ik dan niets te returnen heb 8)7

Ik zat te denken om voor het aanroepen van die native functie steeds een threadje te maken en dan het resultaat in JAVA te kopiëren en dan het threadje te stoppen. Alleen weet ik niet zeker of als je die thread stopt hij dan wel het geheugen van die native functie vrijgeeft.

Iemand die mij op ideeën kan brengen?

Look for the signal in your life, not the noise.

Canon R6 | RF 24-70 f/2.8 L | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 27-03 16:52
Alloceer geheugen voor het resultaat van de native functie in JAVA, voordat je de native functie aanroept. Kopieer de resultaten naar dat geheugen, en dealloceer de desbetreffende pointers in de native functie. Dat kan nu wel. Geen thread voor nodig. Enige probleem is dat het geheugen mogelijk te klein is; retourneer in dat geval hoeveel geheugen nodig was geweest en laat de JAVA kant het nog eens proberen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Gonadan
  • Registratie: Februari 2004
  • Nu online

Gonadan

Admin Beeld & Geluid, Harde Waren
Topicstarter
Ik heb nu geprobeerd om het resultaat te kopiëren en alles te dealloceren.
Dit werkte niet, toen ben ik nog wat verder gaan testen, en nu blijkt dat het volgende het probleem is:
De native functie roept een DLL aan. Die DLL-functie geeft niet al zijn gebruikte geheugen vrij, daar zit het lek dus in.
Die DLL heb ik helaas niet zelf gemaakt dus ik kan er ook niets aan veranderen.
Normaal is dat lekje niet erg, maar omdat ik die functie zo'n 2 miljoen keer moet aanroepen is een klein lekje al schadelijk.
Is er een omweg om dat geheugen alsnog vrij te maken na gebruik van de functie?

Misschien moet dit wel in een nieuw topic, het is een compleet andere vraag geworden ;)

Look for the signal in your life, not the noise.

Canon R6 | RF 24-70 f/2.8 L | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8

Pagina: 1