Olen väsäillyt Java ohjelmaa, joka käsittelee suuria määriä tekstidataa.
Aikansa jauhettuaan, töksähtää kuitenkin seuraavaan:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange(Arrays.java:3209) at java.lang.String.<init>(String.java:215) at java.lang.StringBuilder.toString(StringBuilder.java:430) at TagReader.TagReader.strCut(TagReader.java:138)
eli omassa koodissa kohtaan
private String strCut(String source, int beginIndex, int endIndex) { return source.substring(0, beginIndex) + source.substring(endIndex,source.length()) ; // <--- }
Ohjelma siis siirtelee String-olioista toiseen suuret määrät tekstiä (1 - 500 000 merkkiä), mutta yhteensä tiedon määrä muuttujissa kuitenkin pysyy suht samana, joten muistin loppuminen tuntuu oudolta. Olen kokeillut Netbeansissa muuttaa VM Options parametreja muistin lisäämiseksi; ohjelma tällöin jaksaa toki porskuttaa pidempään, mutta hyytyy ennen loppua samaan tapaan.
Mikä avuksi? :)
Mod. lisäsi kooditagit.
Kokeile String sourcen vaihtamista StringBufferiksi. Ainakin ammoisina aikoina String-olioiden käsittely oli raskasta, koska VM loi niistä operoidessa aina uudet kopiot.
Raskasta ehkä, mutta ei kai se silti selitä muistin loppumista. Kyllä tuo vain kovasti kuulostaa siltä, että jossain kohti jätät turhia muuttujia asustelemaan jonnekin. Testinä voit tulostella muistimääriä eri kohdissa ja kokeilla, kuluttaako jonkin tietyn pätkän ajaminen erityisesti muistia.
public static long freeMemory() { return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); }
Eipä tuo sinun koodinpätkäsi ainakaan siirrä mitään vaan kopioi osan stringistä ja palauttaa sen. Kuten niin usein, tälläkin kertaa virhe tapahtuu jossain muualla kuin siinä kohtaa, mikä laitetaan nettiin näkyville.
Aihe on jo aika vanha, joten et voi enää vastata siihen.