Toon posts:

[JAVA] java.lang.OutOfMemoryError verkomen

Pagina: 1
Acties:

Verwijderd

Topicstarter
In het kort komt mijn vraag hier op neer:
Is het mogelijk om het geheugen dat Java standaard ter beschikking steld te vergroten.

Uitleg:
Ik heb een applicatie die in grote bestanden (> 10 MB) moet kunnen zoeken. Hier voor buffer ik de inhoud van een bestand in een String. Om hier vervolgens een reguliere expressie op los te laten.

buffer=new char[BESTANDGROTE];
buffer=leesBestand();
String bufferstring = new String(buffer,0,BESTANDGROTE);
boolean isGevonden=bufferstring.matches(REGULIEREEXPRESSIE);

Het probleem is dat ik bij bestanden van groter dan 10 MB de melding krijg java.lang.OutOfMemoryError, omdat ik teveel geheugen in gebruik heb volgens Java (minimaal 2xBESTANDSGROTE). Ik vond het een beetje raar dat Java al bij zo'n 30 MB aan geheugen gebruik deze melding geeft, terwijl mijn hardware veel meer aankan. Is dit een bepaalde standaard instelling in Java die de bruikbare geheugen ruimte beperkt? Zo ja hoe kan ik deze verhogen?

Verwijderd

Bij het starten van je applicatie, wat met het volgende commando gaat

java tld.domein.Application

moet je twee parameters meegeven echter deze weet ik even niet
uit mijn hoofd maar zou je even bij java /help moeten kijken.

Het was iets van -Xms128

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Misschien is het ook een idee om je applicatie zodanig aan te passen dat ie zoekt terwijl het bestand ingelezen wordt, of maar een beperkte hoeveelheid tekst opslaat. Het is immers altijd mogelijk dat een bestand groter is dan het beschikbare geheugen...

Verwijderd

Probeer de klasse BufferedReader een, en dan daar een FileReader instoppen.

Verwijderd

Topicstarter
Bedankt voor de reacties!

JeroenBoven: Ik gebruik al BufferedReader met FileReader om de file te lezen hierin zit het probleem niet.

SWfreak: De bestanden waarin ik moet zoeken worden niet veel groter dan 20MB, dus het simpelste is toch om de bruikbare geheugen te vergroten. Zo er geen beperking zitten op de grote van de bestanden ben ik het helemaal met je eens.

BooleanErik: Heb even gekeken in de help en het juiste commando is:
java -Xmx128000000 en hiermee werkt het goed (alleen een beetje traag maar das niet zo gek).

Probleem is dus opgelost! Doe maar op slot!

  • Count
  • Registratie: Augustus 2000
  • Laatst online: 10-08-2023
In een applicatie die langere tijd draait (zoals een socketserver) is het ook zinvol om System.gc() periodiek aan te roepen om de garbagecollection te starten. Tenminste het is mijn ervaring dat zulke java appjes naar verloop van tijd bruut veel geheugen gaan eisen (300mb+) als dat niet gebeurt.

Great minds think in parallel gutters.


Verwijderd

Verwijderd schreef op 17 december 2003 @ 14:05:
Bedankt voor de reacties!

BooleanErik: Heb even gekeken in de help en het juiste commando is:
java -Xmx128000000 en hiermee werkt het goed (alleen een beetje traag maar das niet zo gek).

Probleem is dus opgelost! Doe maar op slot!
Kleine opmerking nog: Vergeet ook niet -Xms te gebruiken. Met alleen -Xmx gebeurt er namelijk wat vreemds:

Het geheugen begint klein, en raakt ook echt op. Als het echt op raakt, alloceerd de VM snel meer geheugen. Dat werkt op zich ok, maar Java code die in de gaten houdt hoeveel geheugen er nog vrij is kan hier op stuk lopen.

Bv, als je net zolang iets alloceerd totdat er nog (zeg) 512KB vrij is. Met alleen -Xmx zul je dan nooit verder komen dan de standaard 2MB (of wat de standaard ook is tegenwoordig).

  • py.mosjuh
  • Registratie: Oktober 2002
  • Laatst online: 24-10-2022

py.mosjuh

fikkert.net

hou er ook rekening mee dat Strings een maximum lengte hebben. ik heb eens ook zoiets geprobeerd met files van zo rond de 50 meg en behoorlijk wat text op een regel en dat vind Java helemaal niet leuk (had 256 meg gealloceerd zoals hierboven ook al staat).

wat jij dus nu doet is symptoombestrijding terwijl je de bron moet aanpakken. gebruik StringBuffer's oid (zijn er niet voor niets imho)

Kites rise highest against the wind - not with it (Winston Churcill)


Verwijderd

Waarom in een String ?

Kun je geen byte array maken die als buffer dient ?

Als je een non-plain text bestandje voert gaat je programma gruwelijk de mist in...

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
Count schreef op 17 december 2003 @ 22:20:
In een applicatie die langere tijd draait (zoals een socketserver) is het ook zinvol om System.gc() periodiek aan te roepen om de garbagecollection te starten. Tenminste het is mijn ervaring dat zulke java appjes naar verloop van tijd bruut veel geheugen gaan eisen (300mb+) als dat niet gebeurt.
slecht gecode socketserver dan wel ;). als je op een server constant 'new' zit te doen is dat niet echt slecht maar zeker niet goed.

met de nio-package kun je alles hergebruiken. Voor een eigen socket server die 1000 clients aankan die allemaal klappen onderling gebruikt het max 12MB (hoe lang het ook draait). die 1000 clients is hardcoded maar een snellere cpu kan er meer aan.

System.gc() is puur 'fictie' een java implementatie hoeft niets te doen (en doen de meeste ook niet) Het is alleen een "hint".

[ Voor 9% gewijzigd door hobbit_be op 18-12-2003 11:33 ]


  • py.mosjuh
  • Registratie: Oktober 2002
  • Laatst online: 24-10-2022

py.mosjuh

fikkert.net

hobbit_be schreef op 18 december 2003 @ 11:33:
System.gc() is puur 'fictie' een java implementatie hoeft niets te doen (en doen de meeste ook niet) Het is alleen een "hint".
het doet wel degelijk iets maar: Java roept telkens al zelf de garbage collector aan wanneer een loop (of wat ook) wordt afgesloten (alles wat binnen die loop zit wordt dan weggegooid: de objecten die daar zijn gemaakt bedoel ik dan en waarnaar ook geen referentie van buiten bestaat). je kan System.gc() gebruiken om veeleisende geheugen allocaties sneller vrij te geven (bijvoorbeeld in een lange loop oid).

Kites rise highest against the wind - not with it (Winston Churcill)


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
py.mosjuh schreef op 18 december 2003 @ 11:38:
het doet wel degelijk iets maar: Java roept telkens al zelf de garbage collector aan wanneer een loop (of wat ook) wordt afgesloten (alles wat binnen die loop zit wordt dan weggegooid: de objecten die daar zijn gemaakt bedoel ik dan en waarnaar ook geen referentie van buiten bestaat). je kan System.gc() gebruiken om veeleisende geheugen allocaties sneller vrij te geven (bijvoorbeeld in een lange loop oid).
Java roept pas z'n garbagecollector aan als hij een bepaald niveau qua geheugengebruik (heap) heeft bereikt. Waar jij imho op doelt is dat hij z'n stack opruimt om alle variabelen die in die scope leven van de stack af te halen en dat heeft niets met gc() te maken.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

py.mosjuh schreef op 18 december 2003 @ 11:38:
het doet wel degelijk iets maar
hobbit_be heeft wel gelijk, het is namelijk alleen een advies aan de vm of hij zo lief wil zijn om te gaan gc`en. Het betekend niet dat het ook meteen gaat gebeuren, dat is namelijk op aan de vm.
: Java roept telkens al zelf de garbage collector aan wanneer een loop (of wat ook) wordt afgesloten (alles wat binnen die loop zit wordt dan weggegooid: de objecten die daar zijn gemaakt bedoel ik dan en waarnaar ook geen referentie van buiten bestaat). je kan System.gc() gebruiken om veeleisende geheugen allocaties sneller vrij te geven (bijvoorbeeld in een lange loop oid).
Ik vind dit typisch een probleem voor de compiler en de vm en daarom betwijfel ik dus ook of het verstandig is om zelf de gc aan te roepen.
Waar jij imho op doelt is dat hij z'n stack opruimt om alle variabelen die in die scope leven van de stack af te halen en dat heeft niets met gc() te maken.
Wel als hij objecten bedoelt ;)

[ Voor 15% gewijzigd door Alarmnummer op 18-12-2003 11:52 ]


Verwijderd

Topicstarter
Bedankt voor de (extra) opmerkingen.

henk_DE_man: Heb je advies over -Xms(256000000) ook toe te voegen geprobeerd. Maar als ik dat doe stopt mijn applicatie er al mee bij het testen van bestanden < 30 MB, geeft de melding out of swap space. Terwijl het zonder deze toevoeging (dus alleen met -Xmx256000000) het wel probleemloos werkt... weet iemand hoe dit komt?

py.nosjuh: Een StringBuffer kan ik niet gebruiken, omdat ik op een reguliere expressie wil testen (dit kan alleen met String.matches()). Voor dezelfde reden valt een character array ook af.

Probleem van niet plain tekst bestanden heb ik niet, omdat het om edi berichten gaat die aan een bepaalde standaard moeten voldoen.

Het gc-en laat ik het lieft toch maar aan de compiler zelf over.

[ Voor 13% gewijzigd door Verwijderd op 18-12-2003 14:49 ]


  • py.mosjuh
  • Registratie: Oktober 2002
  • Laatst online: 24-10-2022

py.mosjuh

fikkert.net

Verwijderd schreef op 18 december 2003 @ 14:42:
Bedankt voor de (extra) opmerkingen.

py.nosjuh: Een StringBuffer kan ik niet gebruiken, omdat ik op een reguliere expressie wil testen (dit kan alleen met String.matches()). Voor dezelfde reden valt een character array ook af.

Het gc-en laat ik het lieft toch maar aan de compiler zelf over.
ik neem aan dat je niet een RE wil testen op 10 meg bestand? deel het dan op in stukken, dan heb je ook het probleem opgelost (nu dus nog steeds niet)...

offtopic:
py.Nosjuh?
:+

[ Voor 22% gewijzigd door py.mosjuh op 18-12-2003 14:46 ]

Kites rise highest against the wind - not with it (Winston Churcill)


Verwijderd

Topicstarter
py.mosjuh schreef op 18 december 2003 @ 14:46:
[...]

ik neem aan dat je niet een RE wil testen op 10 meg bestand? deel het dan op in stukken, dan heb je ook het probleem opgelost (nu dus nog steeds niet)...

offtopic:
py.Nosjuh?
:+
Opdelen is inderdaad wel een mogeljikheid. Zal hier naar kijken of ik dit makkelijk voor elkaar krijg. Maar voorlopig ben ik al tevreden omdat het allemaal goed lijkt te werken, en die grote bestanden toch alleen maar uitzonderingen zijn (bijna alle bestanden zijn rond de 1k).

Verwijderd

Topicstarter
oopz.. dubbel

[ Voor 98% gewijzigd door Verwijderd op 18-12-2003 14:54 ]


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Uit een Reguliere expressie kun je een Reguliere grammatica halen (ze hebben dezelfde uitdrukkingskracht). Wat je dus kunt doen, is de RE omzetten in een RG, voor deze RG een parser laten generen en vervolgens kijken of de boel geparsed wordt.
Pagina: 1