Hoe om te gaan met “java.lang.OutOfMemoryError: Java heap space” fout?

Ik schrijf een client-side Swing-toepassing (grafische lettertypeontwerper) op Java 5. Onlangs kom ik java.lang.OutOfMemoryError: Java heap space-fout tegen omdat ik niet conservatief ben met betrekking tot geheugengebruik. De gebruiker kan een onbeperkt aantal bestanden openen en het programma houdt de geopende objecten in het geheugen. Na een snel onderzoek vond ik Ergonomie in de 5.0 Java Virtual Machine en anderen zeggen dat op een Windows-machine de JVM de maximale heapgrootte standaard instelt als 64MB.

Gegeven deze situatie, hoe moet ik met deze beperking omgaan?

Ik zou de max heap size kunnen vergroten met de opdrachtregel optie naar java, maar daarvoor zou ik de beschikbare RAM moeten uitzoeken en een opstartprogramma of script moeten schrijven. Trouwens, het verhogen tot een eindig maximum lost het probleem uiteindelijk niet op.

Ik zou een deel van mijn code kunnen herschrijven om objecten regelmatig in het bestandssysteem te bewaren (database gebruiken is hetzelfde) om geheugen vrij te maken. Het zou kunnen werken, maar het is waarschijnlijk ook veel werk.

Als je me zou kunnen wijzen op details van bovenstaande ideeën of op enkele alternatieven zoals automatisch virtueel geheugen, waarbij de heap-grootte dynamisch wordt uitgebreid, dan zou dat geweldig zijn.


Antwoord 1, autoriteit 100%

Uiteindelijk heb je altijd een eindige maximale hoeveelheid om te gebruiken, ongeacht op welk platform je draait. In Windows 32 bit is dit rond 2GB (niet specifiek heap maar totale hoeveelheid geheugen per proces). Het gebeurt gewoon dat Java ervoor kiest om de standaard kleiner te maken (vermoedelijk zodat de programmeur geen programma’s kan maken met op hol geslagen geheugentoewijzing zonder dit probleem tegen te komen en te moeten onderzoeken wat ze precies doen).

Dus er zijn verschillende benaderingen die u kunt nemen om te bepalen hoeveel geheugen u nodig heeft of om de hoeveelheid geheugen die u gebruikt te verminderen. Een veelgemaakte fout bij talen die door afval worden verzameld, zoals Java of C#, is om verwijzingen naar objecten die u niet langer gebruikt te bewaren, of om veel objecten toe te wijzen wanneer u ze in plaats daarvan zou kunnen hergebruiken . Zolang objecten een verwijzing naar hen hebben, zullen ze heapruimte blijven gebruiken omdat de vuilnisophaler ze niet zal verwijderen.

In dit geval kunt u een Java-geheugenprofiler gebruiken om te bepalen welke methoden in uw programma een groot aantal objecten toewijzen en vervolgens bepalen of er een manier is om ervoor te zorgen dat er niet langer naar wordt verwezen, of om ze niet toe te wijzen in de eerste plaats. Een optie die ik in het verleden heb gebruikt is “JMP” http://www.khelekore.org/jmp/.

Als u vaststelt dat u deze objecten met een reden toewijst en u referenties moet bewaren (afhankelijk van wat u doet, kan dit het geval zijn), hoeft u alleen de maximale heapgrootte te vergroten wanneer u de programma. Als u echter eenmaal de geheugenprofilering hebt uitgevoerd en begrijpt hoe uw objecten worden toegewezen, zou u een beter idee moeten hebben van hoeveel geheugen u nodig heeft.

Als je niet kunt garanderen dat je programma in een beperkte hoeveelheid geheugen zal draaien (misschien afhankelijk van de invoergrootte), zul je in het algemeen altijd tegen dit probleem aanlopen. Pas nadat je dit allemaal hebt uitgeput, moet je kijken naar het cachen van objecten naar schijf enz. Op dit punt zou je een heel goede reden moeten hebben om te zeggen “Ik heb XGB geheugen nodig” voor iets en je kunt er niet omheen werken door te verbeteren uw algoritmen of geheugentoewijzingspatronen. Over het algemeen zal dit meestal alleen het geval zijn voor algoritmen die werken op grote datasets (zoals een database of een wetenschappelijk analyseprogramma) en dan worden technieken zoals caching en memory-mapped IO nuttig.


Antwoord 2, autoriteit 49%

Voer Java uit met de opdrachtregeloptie -Xmx, die de maximale grootte van de heap instelt.

Zie hier voor details .


Antwoord 3, autoriteit 34%

U kunt per project specificeren hoeveel heapruimte uw project nodig heeft

Het volgende is voor Eclipse Helios/Juno/Kepler:

Klik met de rechtermuisknop op

 Run As - Run Configuration - Arguments - Vm Arguments, 

voeg dit dan toe

-Xmx2048m

Antwoord 4, autoriteit 21%

Het vergroten van de hoop is geen “oplossing”, het is een “pleister”, 100% tijdelijk. Het zal ergens anders weer crashen. Schrijf hoogwaardige code om deze problemen te voorkomen.

  1. Gebruik waar mogelijk lokale variabelen.
  2. Zorg ervoor dat u het juiste object selecteert (EX: Selectie tussen String, StringBuffer en StringBuilder)
  3. Gebruik een goed codesysteem voor uw programma (EX: statische variabelen gebruiken versus niet-statische variabelen)
  4. Andere dingen die op je code kunnen werken.
  5. Probeer te bewegen met multy THREADING

Antwoord 5, autoriteit 11%

Grote waarschuwing —- op mijn kantoor ontdekten we dat (op sommige Windows-machines) we niet meer dan 512 m konden toewijzen voor Java-heap. Dit bleek te wijten te zijn aan het Kaspersky-antivirusproduct dat op sommige van die machines was geïnstalleerd. Na het verwijderen van dat AV-product, ontdekten we dat we ten minste 1,6 GB konden toewijzen, dat wil zeggen, -Xmx1600m (m is verplicht, anders leidt het tot een andere fout “Te kleine initiële heap”) werkt.

Geen idee of dit gebeurt met andere AV-producten, maar vermoedelijk gebeurt dit omdat het AV-programma een klein geheugenblok reserveert in elke adresruimte, waardoor een enkele echt grote toewijzing wordt voorkomen.


Antwoord 6, autoriteit 8%

VM-argumenten werkten voor mij in eclipse. Als je eclipse versie 3.4 gebruikt, doe dan het volgende

ga naar Run --> Run Configurations --> selecteer vervolgens het project onder maven build –> selecteer vervolgens het tabblad “JRE” –> voer vervolgens -Xmx1024m in.

Als alternatief kunt u Run --> Run Configurations --> select the "JRE" tab --> en voer vervolgens –Xmx1024m

in

Dit zou de geheugenheap voor alle builds/projecten moeten vergroten. De bovenstaande geheugengrootte is 1 GB. U kunt optimaliseren zoals u dat wilt.


Antwoord 7, autoriteit 8%

Ik wil graag aanbevelingen toevoegen van oracle probleemoplossing artikel.

Uitzondering in thread thread_name: java.lang.OutOfMemoryError: Java heap space

Het detailbericht Java-heapruimte geeft aan dat het object niet kon worden toegewezen in de Java-heap. Deze fout impliceert niet noodzakelijk een geheugenlek

Mogelijke oorzaken:

  1. Eenvoudig configuratieprobleem, waarbij de opgegeven heapgrootte onvoldoende is voor de toepassing.

  2. Applicatie bevat onbedoeld verwijzingen naar objecten, en dit voorkomt dat de objecten als afval worden verzameld.

  3. Overmatig gebruik van finalizers.

Een andere mogelijke oorzaak van deze fout doet zich voor bij toepassingen die overmatig gebruik maken van finalizers. Als een klasse een finalize-methode heeft, wordt de ruimte van objecten van dat type niet teruggewonnen tijdens het verzamelen van afval

Na vuilnisophaling worden de objecten in de wachtrij geplaatst voor afronding, wat op een later tijdstip plaatsvindt. finalizers worden uitgevoerd door een daemonthread die de finalisatiewachtrij bedient. Als de thread finalizer de finalisatiewachtrij niet kan bijhouden, kan de Java-heap vol raken en zou dit type OutOfMemoryError-uitzondering optreden.

Een scenario dat deze situatie kan veroorzaken, is wanneer een toepassing threads met hoge prioriteit maakt die ervoor zorgen dat de wachtrij finalisatie sneller wordt dan welke de finalizer-thread die wachtrij bedient.


Antwoord 8, autoriteit 7%

Ja, met -Xmx kunt u meer geheugen configureren voor uw JVM.
Om er zeker van te zijn dat u geen geheugen lekt of verspilt. Neem een ​​heap dump en gebruik de Eclipse Memory Analyzer om uw geheugenverbruik te analyseren.


Antwoord 9, autoriteit 4%

Volg onderstaande stappen:

  1. Open catalina.sh vanuit tomcat/bin.

  2. Wijzig JAVA_OPTS in

    JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m 
    -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m 
    -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
    
  3. Herstart je kater


Antwoord 10, autoriteit 3%

Standaard gebruikt JVM voor ontwikkeling een klein formaat en een kleine configuratie voor andere prestatiegerelateerde functies. Maar voor productie kun je b.v. (Bovendien kan er een specifieke applicatieserverconfiguratie bestaan) -> (Als er nog steeds niet genoeg geheugen is om aan het verzoek te voldoen en de heap de maximale grootte al heeft bereikt, zal een OutOfMemoryError optreden)

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size
-XX:ParallelGCThreads=8
-XX:+CMSClassUnloadingEnabled
-XX:InitiatingHeapOccupancyPercent=70
-XX:+UnlockDiagnosticVMOptions
-XX:+UseConcMarkSweepGC
-Xms512m
-Xmx8192m
-XX:MaxPermSize=256m (in java 8 optional)

Bijvoorbeeld: Op linux Platform voor productiemodus voorkeursinstellingen.

Na het downloaden en configureren van de server op deze manier http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/

1.maak setenv.sh-bestand in map /opt/tomcat/bin/

   touch /opt/tomcat/bin/setenv.sh

2.Open en schrijf deze parameters voor het instellen van de voorkeursmodus.

nano  /opt/tomcat/bin/setenv.sh 
export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=8"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+CMSClassUnloadingEnabled"
export CATALINA_OPTS="$CATALINA_OPTS -XX:InitiatingHeapOccupancyPercent=70"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UnlockDiagnosticVMOptions"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseConcMarkSweepGC"
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256M"

3.service tomcat restart

Merk op dat de JVM meer geheugen gebruikt dan alleen de heap. Bijvoorbeeld
Java-methoden, thread-stacks en native handvatten worden in het geheugen toegewezen
gescheiden van de heap, evenals interne gegevensstructuren van JVM.


Antwoord 11, autoriteit 3%

Ik heb ergens anders gelezen dat je het kunt proberen – catch java.lang.OutOfMemoryError en in het catch-blok kun je alle bronnen vrijmaken waarvan je weet dat ze veel geheugen gebruiken, verbindingen sluiten enzovoort, en dan een System.gc() probeer dan opnieuw wat je ging doen.

Een andere manier is dit, hoewel ik niet weet of dit zou werken, maar ik ben momenteel aan het testen of het zal werken op mijn applicatie.

Het idee is om Garbage te verzamelen door System.gc() aan te roepen, waarvan bekend is dat het het vrije geheugen vergroot. Je kunt dit blijven controleren nadat een geheugenschokkende code is uitgevoerd.

//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);
Runtime runtime = Runtime.getRuntime();
if(runtime.freeMemory()<minRunningMemory)
 System.gc();

Antwoord 12, autoriteit 3%

Een gemakkelijke manier om OutOfMemoryError in java op te lossen, is door de maximale heapgrootte te vergroten met behulp van JVM-opties -Xmx512M, dit zal uw OutOfMemoryError onmiddellijk oplossen. Dit is mijn voorkeursoplossing wanneer ik OutOfMemoryError krijg in Eclipse, Maven of ANT tijdens het bouwen van een project, omdat je op basis van de grootte van het project gemakkelijk geen geheugen meer hebt.

Hier is een voorbeeld van het vergroten van de maximale heapgrootte van JVM. Het is ook beter om de verhouding -Xmx tot -Xms 1:1 of 1:1,5 te behouden als u de heapgrootte instelt in uw Java-toepassing.

export JVM_ARGS="-Xms1024m -Xmx1024m"

Referentielink


Antwoord 13, autoriteit 3%

Ik heb hetzelfde probleem ondervonden met de grootte van de Java-heap.

Ik heb twee oplossingen als je java 5(1.5) gebruikt.

  1. installeer gewoon jdk1.6 en ga naar de voorkeuren van eclipse en stel het jre-pad van jav1 1.6 in zoals je hebt geïnstalleerd.

  2. Controleer uw VM-argument en laat het zijn wat het ook is.
    voeg gewoon een regel hieronder toe van alle argumenten die aanwezig zijn in VM-argumenten als
    -Xms512m -Xmx512m -XX:MaxPermSize=…m(192m).

Ik denk dat het zal werken…


Antwoord 14, autoriteit 3%

Als u uw geheugengebruik tijdens runtime moet controleren, biedt het pakket java.lang.management MBeans die kunnen worden gebruikt om de geheugenpools in uw VM te controleren ( bijv. Eden Space, vaste generatie, enz.), en ook afvalophaalgedrag.

De vrije heapruimte die door deze MBeans wordt gerapporteerd, zal sterk variëren, afhankelijk van het GC-gedrag, vooral als uw toepassing veel objecten genereert die later worden geGC-ed. Een mogelijke benadering is om de vrije heapruimte na elke volledige GC te controleren, die u mogelijk kunt gebruiken om een ​​beslissing te nemen over het vrijmaken van geheugen door objecten te behouden.

Uiteindelijk kun je het beste je geheugenretentie zo veel mogelijk beperken terwijl de prestaties acceptabel blijven. Zoals een eerdere opmerking opmerkte, is het geheugen altijd beperkt, maar je app zou een strategie moeten hebben om met geheugenuitputting om te gaan.


Antwoord 15, autoriteit 2%

Houd er rekening mee dat als u dit in een implementatiesituatie nodig hebt, u kunt overwegen om Java WebStart te gebruiken (met een “ondisk” -versie, niet de netwerkversie – mogelijk in Java 6u10 en hoger), omdat u hiermee de verschillende argumenten voor de JVM kunt specificeren op een cross-platform manier.

Anders heb je een besturingssysteem-specifiek opstartprogramma nodig dat de argumenten instelt die je nodig hebt.


Antwoord 16

In Android Studio voeg/wijzig deze regel aan het einde van gradle.properties (Global Properties):

...
org.gradle.jvmargs=-XX\:MaxHeapSize\=1024m -Xmx1024m 

Als het niet werkt, kun je het opnieuw proberen met een grotere heap dan 1024.


Antwoord 17

Als dit probleem zich voordoet in Wildfly 8 en JDK1.8, moeten we MaxMetaSpace-instellingen opgeven in plaats van PermGen-instellingen.

We moeten bijvoorbeeld de onderstaande configuratie toevoegen aan het setenv.sh-bestand van wildfly.
JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"

Ga voor meer informatie naar Wildfly Heap Issue


Antwoord 18

Met betrekking tot netbeans kunt u de maximale heapgrootte instellen om het probleem op te lossen.

Ga naar ‘Uitvoeren’, dan –> ‘Projectconfiguratie instellen’ –> ‘Aanpassen’ –> ‘uitvoeren’ van het pop-upvenster –> ‘VM-optie’ –> vul ‘-Xms2048m in -Xmx2048m’.


Antwoord 19

Als u & door verwijzingen naar het object te bewaren, vult u elke hoeveelheid geheugen die u heeft.

Een optie is om een ​​transparant bestand te sluiten & openen wanneer ze van tabblad wisselen (u houdt alleen een aanwijzer naar het bestand, en wanneer de gebruiker van tabblad wisselt, sluit u en maakt u alle objecten schoon… het zal het bestand langzamer veranderen… maar…), en bewaar misschien maar 3 of 4 bestanden in het geheugen.

Anders wat u moet doen is, wanneer de gebruiker een bestand opent, het laadt en een eventuele OutOfMemoryError onderschept, dan (omdat het niet mogelijk is om het bestand te openen) dat bestand sluit, de objecten opschont en de gebruiker waarschuwt dat hij zou ongebruikte bestanden moeten sluiten.

Uw idee van het dynamisch uitbreiden van virtueel geheugen lost het probleem niet op, want de machine heeft beperkte middelen, dus u moet voorzichtig zijn & geheugenproblemen afhandelen (of er in ieder geval voorzichtig mee zijn).

Een paar hints die ik heb gezien met geheugenlekken zijn:

–> Houd er rekening mee dat als je iets in een verzameling stopt en het daarna vergeet, je er nog steeds een sterke verwijzing naar hebt, dus vernietig de verzameling, maak hem schoon of doe er iets mee… zal een geheugenlek moeilijk vinden.

–> Misschien kan het gebruik van collecties met zwakke referenties (weakhashmap…) helpen bij geheugenproblemen, maar je moet er voorzichtig mee zijn, want je zou kunnen vinden dat het object dat je zoekt is verzameld.

–> Een ander idee dat ik heb gevonden, is het ontwikkelen van een permanente collectie die is opgeslagen op database-objecten die het minst worden gebruikt en transparant worden geladen. Dit zou waarschijnlijk de beste aanpak zijn…


Antwoord 20

Als deze fout optreedt direct na het uitvoeren van uw junit-tests, moet u Build -> uitvoeren. Project herbouwen.


Antwoord 21

Als al het andere faalt, probeer dan naast het vergroten van de maximale heapgrootte ook de swapgrootte te vergroten. Voor Linux zijn vanaf nu relevante instructies te vinden in https:// linuxize.com/post/create-a-linux-swap-file/.

Dit kan helpen als je b.v. iets groots compileren in een ingebed platform.


Antwoord 22

als je deze foutmelding krijgt bij het starten van eclipse birt
1- je gaat in het bestand van de eclipsconfiguratie
2- je moet eclipse.init openen
3- het RAM-geheugen aangepast, je kunt dit vergroten, ik geef een voorbeeld.

mijn oude informatie was:
-Xmx128m
-XX:MaxPermSize=128m

de nieuwe wijziging die ik heb uitgevoerd :

-Xmx512m
-XX:MaxPermSize=512m

Deze wijziging stelt me ​​in staat om java-heapruimte op te lossen wanneer ik mijn rapport in mijn browser start.

Bedankt


Antwoord 23

Android Studio

Bestand -> Caches ongeldig maken en opnieuw opstarten heeft het voor mij opgelost 🙂


Antwoord 24

Java OOM Heap-ruimteprobleem kan ook optreden wanneer uw DB-verbindingspool vol raakt.

Ik heb met dit probleem te maken gehad omdat mijn Hikari Connection-pool (bij de upgrade naar Spring boot 2.4.*) vol was en geen verbindingen meer kon bieden (alle actieve verbindingen zijn nog in behandeling om resultaten uit de database op te halen).

Probleem is dat sommige van onze native zoekopdrachten in JPA Repositories ORDER BY ?#{#pageable} bevatten, wat erg lang duurt voordat er resultaten worden verkregen bij een upgrade.

ORDER BY ?#{#pageable} verwijderd uit alle native queries in JPA-repositories en het probleem met de OOM-heapruimte en het probleem met de verbindingspool zijn opgelost.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

11 + eleven =

Other episodes