Inhaltsverzeichnis
Java-Speicherleckproblem
Anhang: Typische Situationen von Speicherlecks
Heim Java javaLernprogramm Fallanalyse von Java-Speicherverlustproblemen

Fallanalyse von Java-Speicherverlustproblemen

May 23, 2023 pm 06:46 PM
java

Java-Speicherleckproblem

Der sogenannte Speicherverlust bedeutet, dass ein Objekt oder eine Variable, die nicht mehr vom Programm verwendet wird, im Speicher belegt ist.

In Java gibt es einen Garbage-Collection-Mechanismus, der sicherstellen kann, dass, wenn auf ein Objekt nicht mehr verwiesen wird, das heißt, wenn das Objekt verwaist wird, das Objekt durch den Müll automatisch aus dem Speicher gelöscht wird Kollektor.

Da Java über einen Garbage-Collection-Mechanismus verfügt, warum gibt es immer noch ein Speicherverlustproblem?

Es ist nur so, dass einige Objekte nicht vom Garbage Collector verarbeitet werden können, was dazu führt, dass diese Objekte ständig den JVM-Speicher belegen, was zu Speicherverlusten führt.

Da Java einen gerichteten Graphen für die Speicherbereinigungsverwaltung verwendet, kann das Problem von Referenzzyklen beseitigt werden. Beispielsweise gibt es zwei Objekte, die aufeinander verweisen, solange sie nicht erreichbar sind Dann kann der GC sie auch recyceln. Der folgende Code kann in diesem Fall beispielsweise das Speicherrecycling sehen.

import java. io.IOException;
public class GarbageTest {

    public static void main(String[] args) throws IOException {
        try {
            // TODO Auto-generated method stub
            gcTest();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("has exited gcTest!");
        System.in.read();
        System.in.read();
        System.out.println("out begin gc!");
        for (int i = 0; i < 100; i++) {
            System.gc();
            System.in.read();
            System.in.read();
        }
    }

    private static void gcTest() throws IOException {
        System.in.read();
        System.in.read();
        Person p1 = new Person();
        System.in.read();
        System.in.read();
        Person p2 = new Person();
        p1.setMate(p2);
        p2.setMate(p1);
        System.out.println("before exit gctest!");
        System.in.read();
        System.in.read();
        System.gc();
        System.out.println("exit gctest!");
    }

    private static class Person {
        byte[] data = new byte[20000000];
        Person mate = null;

        public void setMate(Person other) {
            mate = other;
        }
    }

}
Nach dem Login kopieren

Speicherlecks in Java: Wenn langlebige Objekte Verweise auf kurzlebige Objekte enthalten, treten wahrscheinlich Speicherlecks auf, obwohl die kurzlebigen Objekte nicht mehr benötigt werden, da A langlebig ist Das Objekt enthält einen Verweis darauf und kann nicht recycelt werden. Laienhaft ausgedrückt kann es sein, dass der Programmierer ein Objekt erstellt und es dann nie wieder verwendet immer referenziert, das heißt, dieses Objekt ist nutzlos, kann aber nicht vom Garbage Collector recycelt werden. Dies ist ein möglicher Speicherverlust in Java.

Zum Beispiel laden wir im Cache-System ein Objekt und legen es in den Cache (z. B. in ein globales Kartenobjekt) und verwenden es dann nie wieder. Der Wert dieses Objekts ist Wird vom Cache referenziert, aber nicht mehr verwendet.

Um in Java nach Speicherlecks zu suchen, müssen Sie das Programm alle Zweige bis zum Ende des Programms vollständig ausführen lassen und dann prüfen, ob ein Objekt verwendet wurde. Wenn nicht, können Sie dies feststellen Das Objekt gehört zu einem Speicherverlust.

Wenn die Methode eines Instanzobjekts einer externen Klasse ein Instanzobjekt einer internen Klasse zurückgibt, wird das interne Klassenobjekt für lange Zeit referenziert, auch wenn das Instanzobjekt der externen Klasse nicht mehr verwendet wird , aber aufgrund der internen Klasseninstanzobjekte persistenter externer Klassen wird dieses externe Klassenobjekt nicht durch Müll gesammelt, was ebenfalls zu Speicherverlusten führt.

Der folgende Inhalt stammt aus dem Internet (die Hauptfunktion besteht darin, ein Element im Stapel zu löschen, nicht um es vollständig aus dem Array zu entfernen, sondern um die insgesamt gespeicherte Menge zu reduzieren. Ich kann es besser schreiben als dies Okay, wenn Sie ein Element entfernen, lassen Sie es aus dem Array verschwinden und setzen Sie den Wert der Position des Elements auf Null)

Ich kann mir wirklich nichts Klassischeres vorstellen als diesen Stapel Beispiele, Deshalb muss ich die Beispiele anderer Leute zitieren, die mir nicht eingefallen sind, sondern die, die ich in dem Buch gesehen habe. Natürlich könnte es mir nach einer Weile selbst einfallen, wenn ich sie nicht gesehen hätte , aber als ich dann sagte, dass ich selbst daran gedacht hätte, glaubte es niemand.

public class Stack {
    private Object[] elements = new Object[10];
    private int size = 0;

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop() {
        if (size == 0) throw new EmptyStackException();
        return elements[--size];
    }

    private void ensureCapacity() {
        if (elements.length == size) {
            Object[] oldElements = elements;
            elements = new Object[2 * elements.length + 1];
            System.arraycopy(oldElements, 0, elements, 0, size);
        }
    }
}
Nach dem Login kopieren

Das obige Prinzip sollte sehr einfach sein. Wenn 10 Elemente zum Geldhaufen hinzugefügt werden und dann alle auftauchen, obwohl der Geldhaufen leer ist und wir nichts wollen, ist dies der Fall ist ein Objekt, das nicht recycelt werden kann. Es erfüllt die beiden Bedingungen für Speicherlecks. Es ist nutzlos und kann nicht recycelt werden. Aber selbst die Existenz eines solchen Dings hat möglicherweise keine Konsequenzen. Wenn dieser Haufen Geld weniger verwendet wird, werden nur ein paar K Speicher verschwendet. Wie auch immer, unser Gedächtnis ist bereits über G, also welche Auswirkungen wird es haben? ? Außerdem wird das Ding bald recycelt, also was macht das schon? Schauen wir uns unten zwei Beispiele an.

class Bad {
    public static Stack s = new Stack();
    static {
        s.push(new Object());

        s.pop(); //这里有一个对象发生内存泄露

        s.push(new Object());//上面的对象可以被回收了,等于是自愈了
    }
}
Nach dem Login kopieren

Da es statisch ist, bleibt es bestehen, bis das Programm beendet wird, aber wir können auch sehen, dass es über eine Selbstheilungsfunktion verfügt, was bedeutet, dass Ihr Stack maximal 100 Objekte enthält Es werden nur maximal 100 Objekte vorhanden sein, die nicht recycelt werden können. Tatsächlich sollte es leicht zu verstehen sein, dass der Stapel 100 Referenzen enthält verschwinden natürlich!

Eine weitere Situation eines Speicherverlusts: Wenn ein Objekt in der HashSet-Sammlung gespeichert wird, können die Felder im Objekt, die an der Berechnung des Hash-Werts beteiligt sind, nicht geändert werden. Andernfalls wird das geänderte Objekt geändert unterscheidet sich vom Hashwert, als er ursprünglich in der HashSet-Sammlung gespeichert wurde. In diesem Fall gibt die Methode „Not Found“ die aktuelle Referenz des Objekts als Parameter zum Abrufen des Objekts zurück Dies führt auch dazu, dass das aktuelle Objekt nicht einzeln aus der HashSet-Sammlung gelöscht werden kann, was zu einem Speicherverlust führt.

Anhang: Typische Situationen von Speicherlecks

(1) Temporäres Speicherleckproblem, das durch die Datenstruktur verursacht wird, siehe folgenden Code

public class Stack{  
      private Object[] element=new Object[10];  
      private int size=0;  
        
      public void push(Object ele){  
             ensureCapacity();  
             element[size++]=ele;  
      }  
  
      public Object pop(){  
             if(size==0) throw new EmptyStackException();  
             return element[--size]; //短暂造成内存泄露  
      }  
  
      private void ensureCapacity(){  
             if(element.length==size){  
                     Object[] oldElement=element;  
                     element=new Object[size*2+1];  
                     System.arraycopy(oldElement,0,element,0,size);  
             }  
      }  
}
Nach dem Login kopieren

Above Every Sobald der Code erscheint (), wird ein Element im Stapel angezeigt. Bevor ein neues Element hinzugefügt wird, gibt es tatsächlich noch ein Referenzelement[x], das auf das entfernte Objekt verweist, sodass der GC es nicht im Müll sammelt. Nur durch das Setzen von element[x]=newObject beim push() eines neuen Elements können zuvor erstellte Objekte recycelt werden. Es wäre viel sicherer, die obige pop()-Methode in den folgenden Code zu ändern:

public Object pop(){  
       if(element.length==size) throws EmptyStackException();  
       Object o=element[--size];  
       elements[size]=null;  //使得GC有机会回收这个对象  
       return o;  
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonFallanalyse von Java-Speicherverlustproblemen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Java -Programm, um das Kapselvolumen zu finden Java -Programm, um das Kapselvolumen zu finden Feb 07, 2025 am 11:37 AM

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

PHP vs. Python: Verständnis der Unterschiede PHP vs. Python: Verständnis der Unterschiede Apr 11, 2025 am 12:15 AM

PHP und Python haben jeweils ihre eigenen Vorteile, und die Wahl sollte auf Projektanforderungen beruhen. 1.PHP eignet sich für die Webentwicklung mit einfacher Syntax und hoher Ausführungseffizienz. 2. Python eignet sich für Datenwissenschaft und maschinelles Lernen mit präziser Syntax und reichhaltigen Bibliotheken.

PHP: Eine Schlüsselsprache für die Webentwicklung PHP: Eine Schlüsselsprache für die Webentwicklung Apr 13, 2025 am 12:08 AM

PHP ist eine Skriptsprache, die auf der Serverseite weit verbreitet ist und insbesondere für die Webentwicklung geeignet ist. 1.PHP kann HTML einbetten, HTTP -Anforderungen und Antworten verarbeiten und eine Vielzahl von Datenbanken unterstützt. 2.PHP wird verwendet, um dynamische Webinhalte, Prozessformdaten, Zugriffsdatenbanken usw. mit starker Community -Unterstützung und Open -Source -Ressourcen zu generieren. 3. PHP ist eine interpretierte Sprache, und der Ausführungsprozess umfasst lexikalische Analyse, grammatikalische Analyse, Zusammenstellung und Ausführung. 4.PHP kann mit MySQL für erweiterte Anwendungen wie Benutzerregistrierungssysteme kombiniert werden. 5. Beim Debuggen von PHP können Sie Funktionen wie error_reporting () und var_dump () verwenden. 6. Optimieren Sie den PHP-Code, um Caching-Mechanismen zu verwenden, Datenbankabfragen zu optimieren und integrierte Funktionen zu verwenden. 7

Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Oct 13, 2024 pm 01:32 PM

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.

See all articles