Contre-mesures pour OutOfMemoryError en java

Fondamentalement, il est nécessaire d'enquêter et d'analyser avec gcviewer-1.36 ou Memory Analyzer pour identifier la cause. Dans mon cas, je dois enregistrer un gros objet toutes les secondes et j'obtiens une erreur en moins d'une heure.

Contre-mesure:

1. Ajoutez de la mémoire VM (si nécessaire)

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. En volant le poids à la source, dans le cas de la même chaîne ou objet, il sera sauvegardé dans la mémoire comme un seul.

classe de base poids mouche

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);
        }
    }
}

classe d'implémentation flyweight

TsunamiBinaryPointBean.java


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

    /**
     *Définir l'ID de point
     */
	public void setPointID(String pointID){
		this.pointID = StringUtil.flyweightOf(pointID);
	}

    /**
     *Réglage de la mémoire, objets poids mouche
     */
    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. Toujours inutile, enregistrez en mémoire sous forme de binaire compressé au lieu d'un objet

compression

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,"Compression ByteBuffer", "Une erreur est survenue.", 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;
        }
    }

Dégivrer

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,"Décompression ByteBuffer", "Une erreur est survenue. Vérifiez l'exactitude de 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;
        }
    }

Sortie binaire

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();
    }

Réception binaire Ce qui est produit par DataOutputStream n'est reçu que par DataInputStream et, dans d'autres cas, il devient une opération non voulue.

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

Contre-mesures pour OutOfMemoryError en java
Pour l'apprentissage JAVA (2018-03-16-01)
IDE 2017 pour Java
contre-mesures d'erreur java
Java pour instruction
[Java] pour instruction, while instruction
[Java] Package de gestion
[Java] pour instruction / étendu pour instruction
PNL pour Java (NLP4J) (2)
(Mémo) Java pour instruction
PNL pour Java (NLP4J) (1)
Mesures Java Gold: Format
Mesures Java Gold: localisation
Le débogueur Java VSCode pour la construction Java a échoué Causes et contre-mesures
Exécution de débogage Java [pour les débutants Java]
[Java] Instruction de base pour les débutants
Livres utilisés pour apprendre Java
Test de compétence Java 2018 pour les nouveaux arrivants - Principes de base-
Java thread sans danger pour vous
Java pour les débutants, masquage des données
[Java] Conseils pour l'écriture de la source
Emplacement d'installation Java pour Mac
Application Java pour les débutants: stream
Instructions Java while et for
Aide-mémoire C # pour les techniciens Java
Nouvelle syntaxe pour les instructions Java 12 Switch
[Pour les débutants] Résumé du constructeur java
SDK AWS pour Java 1.11.x et 2.x
Les débutants jouent à des jeux Janken en Java
Java pour les débutants, les expressions et les opérateurs 1
[Java] Mémo pour nommer les noms de classe
[Pour les débutants] Exécutez Selenium sur Java
Hello World pour le plugin Java ImageJ
[OpenCV3.2.0] Paramètres Eclipse (Java) (pour Mac)
Java pour les débutants, les expressions et les opérateurs 2
Activez OpenCV avec java8. (Pour moi-même)
Outils Spring Framework pour développeur Java
java (utilisez le type de classe pour le champ)
Création d'un environnement de développement Java (pour Mac)
Java
[Java & SpringBoot] Construction de l'environnement pour Mac
Paramètres de débogage SSL dans Java
Génériques Kotlin pour les développeurs Java
Java
Agenda pour la qualification Java SE 8 Silver
[Pour les débutants en Java] À propos de la gestion des exceptions
Classes et instances Java pour les débutants
Meilleures pratiques modernes pour les tests Java
GraalVM for Java Performance (Windows Developer Build)
Implémentation de la méthode de clonage pour Java Record
[Jusqu'au 5 mars 2020] Renouveler le certificat RDS pour java
Premiers pas avec Ruby pour les ingénieurs Java
[Java Spring MVC] Contrôleur de confirmation de développement
Mesure de la mémoire pour les applications Java utilisant jstat
Introduction à Java pour la première fois # 2
Contre-mesures pour l'échec de la construction de FDclone sur CentOS 8
Premiers pas pour l'apprentissage profond en Java
Java pour tous! J'ai lu tout le monde en Java #minjava