Gegenmaßnahmen für OutOfMemoryError in Java

Grundsätzlich ist es notwendig, mit gcviewer-1.36 oder Memory Analyzer zu untersuchen und zu analysieren, um die Ursache zu identifizieren. In meinem Fall muss ich jede Sekunde ein großes Objekt speichern, und in weniger als einer Stunde wird ein Fehler angezeigt.

Gegenmaßnahme:

1. Fügen Sie VM-Speicher hinzu (falls erforderlich)

startup_parameters.sh


appserver_mem="6000m"
appserver_java_opt="-Xms=3074m -Xmx=3074m -XX:PermSize=1024m -XX:MaxPermSize=1024m -XX:NewSize=1024m -XX:MaxNewSize=1024m  -server -Djava.awt.headless=true"

2. Wenn Sie Gewicht zur Quelle fliegen, wird es im Fall desselben Strings oder Objekts als eins im Speicher gespeichert.

Fliegengewicht Kernklasse

FlyweightPool.java


package util;

import java.lang.ref.WeakReference;
import java.util.WeakHashMap;

public class FlyweightPool<T> {

    private WeakHashMap<T, WeakReference<T>> pool = new WeakHashMap<>();
    public FlyweightPool() {}


    public T flyweightOf(T obj) {
        if (obj == null) {
            return null;
        }
        synchronized(pool) {
            WeakReference<T> w = pool.get(obj);
            T flyweihgt = (w == null ? null : w.get());
            if (flyweihgt != null) {
                return flyweihgt;
            }
            pool.put(obj, new WeakReference<T>(obj));
            return obj;
        }
    }

    public boolean contains(T obj) {
        synchronized (pool) {
            return pool.containsKey(obj);
        }
    }

    public void remove(T obj) {
        synchronized (pool) {
            pool.remove(obj);
        }
    }
}

Flyweight Implementierungsklasse

TsunamiBinaryPointBean.java


    private static final FlyweightPool<List<TsunamiBinaryFauldBean>> listFlyweights = new FlyweightPool<>();
    private static final FlyweightPool<TsunamiBinaryFauldBean> dataFlyweight = new FlyweightPool<>();

    /**
     *Stellen Sie die Punkt-ID ein
     */
	public void setPointID(String pointID){
		this.pointID = StringUtil.flyweightOf(pointID);
	}

    /**
     *Speicheroptimierung, Objekte im Fliegengewicht
     */
    public void optimizeMemory() {
        List<TsunamiBinaryFauldBean> fauldBean;
        synchronized(this.tsunamiBinaryFaulds) {
        	TsunamiBinaryFauldBean[] dataArr = new TsunamiBinaryFauldBean[this.tsunamiBinaryFaulds.size()];
            for (int i = 0; i < this.tsunamiBinaryFaulds.size(); i++) {
                dataArr[i] = dataFlyweight.flyweightOf(this.tsunamiBinaryFaulds.get(i));
            }
            fauldBean = listFlyweights.flyweightOf(Arrays.asList(dataArr));
        }
        this.tsunamiBinaryFaulds = fauldBean;
    }

3. Immer noch nutzlos, im Speicher als komprimierte Binärdatei anstelle eines Objekts speichern

Kompression

XXX.java


    public static ByteBuffer compress(ByteBuffer buffer){
        ByteArrayOutputStream compressBaos = new ByteArrayOutputStream();
        GZIPOutputStream gzip = null;
        try{
            gzip = new GZIPOutputStream(compressBaos) {{
                def.setLevel(Deflater.BEST_COMPRESSION);
             }};
            gzip.write(buffer.array());
            gzip.finish();
            gzip.flush();
            compressBaos.flush();
            
            byte[] compressed = compressBaos.toByteArray();
            return ByteBuffer.wrap(compressed);
        }catch(IOException e){
        	DonetLogger.LOGGER.error(1,"ByteBuffer-Komprimierung", "Ein Fehler ist aufgetreten.", e);
        	return null;
        }finally{
        	try{
        		if(gzip != null){
        			gzip.close();
        		}
        	}catch(Exception e){}
        	try{
        		if(compressBaos != null){
        			compressBaos.close();
        		}
        	}catch(Exception e){}
        	gzip = null;
        	compressBaos = null;
        }
    }

Auftauen

XXX.java


public static ByteBuffer decompress(ByteBuffer buffer){
        ByteArrayOutputStream decompressBaos = new ByteArrayOutputStream();
        GZIPInputStream gzip = null;
        byte[] b = new byte[1024*100];
        try{
            gzip = new GZIPInputStream(new ByteArrayInputStream(buffer.array()));
            for (int read = gzip.read(b); read >= 0; read = gzip.read(b)) {
            	decompressBaos.write(b, 0, read);
            }
            decompressBaos.flush();
            byte[] decompressed = decompressBaos.toByteArray();
            return ByteBuffer.wrap(decompressed);
        }catch(IOException e){
        	DonetLogger.LOGGER.error(1,"ByteBuffer-Dekomprimierung", "Ein Fehler ist aufgetreten. Überprüfen Sie die Genauigkeit von ByteBuffer.", e);
        	return null;
        }finally{
        	try{
        		if(gzip != null){
        			gzip.close();
        		}
        	}catch(Exception e){}
        	try{
        		if(decompressBaos != null){
        			decompressBaos.close();
        		}
        	}catch(Exception e){}
        	gzip = null;
        	decompressBaos = null;
        }
    }

Binäre Ausgabe

XXX.java


    public void binaryWrite(DataOutputStream output) throws IOException{
    	if(this.getPointCount() <= 0){
    		return;
    	}
		output.writeUTF(this.header);
		output.writeUTF(toSimpleDateTimeString(this.tsunamiDatetime));
		output.writeShort(pointCount);
    	for(TsunamiBinaryPointBean point :tsunamiBinaryPoints){
    		output.writeUTF(point.getAreaID());
    		output.writeUTF(point.getPointID());
    		output.writeFloat(point.getLineAbsAverage());
    		output.writeShort(point.getFauldCount());
    		output.writeFloat(point.getFirstLineAbsAverage());
        	for(int i=0; i<point.getTsunamiBinaryFaulds().length; i++){
        		output.writeUTF(point.getTsunamiBinaryFaulds()[i].getFauldID());
        		output.writeUTF(point.getTsunamiBinaryFaulds()[i].getStartDatetime());
        		output.writeFloat(point.getTsunamiBinaryFaulds()[i].getAmplificationFactor());
        		output.writeFloat(point.getTsunamiBinaryFaulds()[i].getFauldAbsAverageValue());
        	}
    	}
	    output.flush();
    }

Binärer Empfang Was von DataOutputStream ausgegeben wird, wird nur von DataInputStream empfangen, und in anderen Fällen wird es zu einer unbeabsichtigten Operation.

XXX.java


   public static ByteBuffer toByteBuffer(DataInputStream input){
    	ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    	DataOutputStream out = new DataOutputStream(buffer);
    	byte[] result;
    	try{
	    	out.writeUTF(input.readUTF());
			out.writeUTF(input.readUTF());
			int point = input.readShort();
			out.writeShort(point);
			for(int i=0;i<point;i++){
				out.writeUTF(input.readUTF());
				out.writeUTF(input.readUTF());
				out.writeFloat(input.readFloat());
				int fauld = input.readShort();
				out.writeShort(fauld);
				out.writeFloat(input.readFloat());
				for(int j=0;j<fauld;j++){
					out.writeUTF(input.readUTF());
					out.writeUTF(input.readUTF());
					out.writeFloat(input.readFloat());
					out.writeFloat(input.readFloat());
				}
			}
			result = buffer.toByteArray();
			return ByteBuffer.wrap(result);
		}catch(IOException e){
			return null;
		}finally{
	        try {
	            if (out != null) {
	            	out.close();
	            }
	        }catch (IOException e) {}
	        try {
	            if (buffer != null) {
	            	buffer.close();
	            }
	        }catch (IOException e) {}
	    	buffer = null;
	    	out = null;
		}
    }

Recommended Posts

Gegenmaßnahmen für OutOfMemoryError in Java
Für JAVA-Lernen (2018-03-16-01)
2017 IDE für Java
Gegenmaßnahmen gegen Java-Fehler
Java für Anweisung
[Java] für Anweisung, während Anweisung
[Java] Paket für die Verwaltung
[Java] für Anweisung / erweitert für Anweisung
NLP für Java (NLP4J) (2)
(Memo) Java für Anweisung
NLP für Java (NLP4J) (1)
Java Gold misst: Format
Java Gold misst: Lokalisierung
VSCode Java Debugger für Java Build fehlgeschlagen Ursachen und Gegenmaßnahmen
Java-Debug-Ausführung [für Java-Anfänger]
[Java] Grundlegende Aussage für Anfänger
Bücher zum Erlernen von Java
2018 Java Proficiency Test für Newcomer-Basics-
Java-Thread sicher für Sie
Java für Anfänger, Daten verstecken
[Java] Tipps zum Schreiben der Quelle
Java-Installationsort für Mac
Java-Anwendung für Anfänger: Stream
Java während und für Anweisungen
C # Spickzettel für Java-Techniker
Neue Syntax für Java 12 Switch-Anweisungen
[Für Anfänger] Zusammenfassung des Java-Konstruktors
AWS SDK für Java 1.11.x und 2.x.
Anfänger spielen Janken-Spiele in Java
Java für Anfänger, Ausdrücke und Operatoren 1
[Java] Memo zum Benennen von Klassennamen
[Für Anfänger] Führen Sie Selenium auf Java aus
Hallo Welt für ImageJ Java Plugin
[OpenCV3.2.0] Eclipse (Java) -Einstellungen (für Mac)
Java für Anfänger, Ausdrücke und Operatoren 2
Aktivieren Sie OpenCV mit Java8. (Für mich)
Spring Framework-Tools für Java-Entwickler
Java (Klassentyp für Feld verwenden)
Erstellen einer Java-Entwicklungsumgebung (für Mac)
Java
[Java & SpringBoot] Umgebungskonstruktion für Mac
Einstellungen für das SSL-Debugging in Java
Kotlin-Generika für Java-Entwickler
Java
Tagebuch für Java SE 8 Silber Qualifikation
[Für Java-Anfänger] Informationen zur Ausnahmebehandlung
Klassen und Instanzen Java für Anfänger
Moderne Best Practices für Java-Tests
GraalVM für Java-Leistung (Windows Developer Build)
Implementierung der Klonmethode für Java Record
[Bis 5. März 2020] Erneuern Sie das RDS-Zertifikat für Java
Erste Schritte mit Ruby für Java-Ingenieure
[Java Spring MVC] Entwicklungsbestätigungscontroller
Speichermessung für Java-Apps mit jstat
Einführung in Java zum ersten Mal # 2
Gegenmaßnahmen für FDclone-Build-Fehler unter CentOS 8
Erste Schritte für tiefes Lernen in Java
Java für alle! Ich habe jedermanns Java #minjava gelesen