2009-10-17 15 views

Antwort

24

Es wird ausgeführt, wenn festgestellt wird, dass es Zeit zum Ausführen ist. Eine allgemeine Strategie bei generationellen Speicherbereinigern besteht darin, den Kollektor auszuführen, wenn eine Zuweisung von Speicher der Generation 0 fehlschlägt. Das heißt, jedes Mal, wenn Sie einen kleinen Speicherblock zuweisen (große Blöcke werden normalerweise direkt in "ältere" Generationen platziert), prüft das System, ob im gen-0-Heap genügend freier Speicherplatz vorhanden ist, und falls nicht, wird es ausgeführt der GC, um Speicherplatz freizumachen, damit die Zuweisung erfolgreich ist. Alte Daten werden dann in den Gen-1-Heap verschoben, und wenn dort Speicherplatz frei wird, führt der GC eine Sammlung aus, aktualisiert die Daten, die am längsten dort waren, zum Gen-2-Heap und so weiter. Also "läuft" der GC nicht. Es könnte nur auf dem gen-0-Heap laufen (und die meisten Sammlungen werden genau das tun), oder es könnte jede Generation prüfen, ob es wirklich viel Speicher freimachen muss (was nur ziemlich selten notwendig ist).

Aber das ist weit von der nur Strategie. Ein paralleler GC wird im Hintergrund ausgeführt und bereinigt, während das Programm ausgeführt wird. Einige GCs können als Teil jeder Speicherzuweisung ausgeführt werden. Ein inkrementeller Kollektor könnte dies tun, indem er bei jeder Speicherzuweisung ein paar Objekte scannt.

Der gesamte Punkt in einem Garbage Collector ist, dass es einfach seine Sache tun sollte, ohne dass eine Eingabe vom Benutzer erforderlich ist. Im Allgemeinen können und sollten Sie nicht vorhersagen, wann es ausgeführt wird.

Ich glaube, Suns JVM hat vor nicht allzu langer Zeit einen Generations-GC bekommen (v1.6 vielleicht? Ich habe Java seit Ewigkeiten nicht programmiert, also bin ich mir da nicht sicher, aber ich erinnere mich, vor nicht allzu langer Zeit überrascht worden zu sein der Verkaufsargumente für die neue Version war "ein Generations-GC". Nicht zuletzt, weil .NET seit Tag 1 eine gehabt hat.)

Andere JVMs sind natürlich frei, die Strategie auszuwählen, die sie mögen.

EDIT: Der obige Teil über Java und Generations-GC ist nicht wahr. Weitere Informationen finden Sie unten:

Die virtuellen Maschinen 1.0 und 1.1 verwendeten einen Mark-Sweep-Collector, der den Heap nach einer Garbage Collection fragmentieren konnte. Beginnend mit Java 1.2, wechselten die virtuellen Maschinen zu einem Generationskollektor, der ein viel besseres Defragmentierungsverhalten hat (siehe Java theory and practice: Garbage collection and performance).

So Java hat eigentlich eine Generation GC für Ewigkeiten. Neu in Java 6 ist der Garbage-First Garbage Collector (G1), der in Java 6u14 verfügbar ist. Nach the article claiming the release in 1.6.0_14: Es ist nicht standardmäßig aktiviert. Der Parallelsammler ist immer noch der Standard-GC und ist der effizienteste GC für den Hausgebrauch. G1 soll eine Alternative für den gleichzeitigen Kollektor sein. Es ist so konzipiert, dass es vorhersehbarer ist und eine schnelle Zuweisung mit Speicherbereichsdesign ermöglicht.

+0

Java hat seit JDK 1.3 einen Generations-GC (siehe zB http://www.javaworld.com/javaworld/jw-01-2002/jw-0111-hotspotgc.html) –

+1

@Johannes Weiß Nein, seit JDK 1.2 . Die virtuellen Maschinen 1.0 und 1.1 verwendeten einen Mark-Sweep-Collector, der den Heap nach einer Garbage Collection fragmentieren konnte. Beginnend mit Java 1.2, wechselten die virtuellen Maschinen zu einem Generationskollektor, der ein viel besseres Defragmentierungsverhalten hat. Siehe http://www.ibm.com/developerworks/library/j-jtp01274.html. –

+0

@Pascal Thivent: Ok, der Artikel, mit dem ich verlinkt habe, sagte, dass JDK1.2 einen 'exakten Garbage Collector' hatte, der in 'JDK 1.3' zu 'generational GC' umbenannt wurde, aber vielleicht hast du recht ... –

5

Es hängt viel davon ab, was Garbage Collector Sie tatsächlich verwenden, wie es abgestimmt ist, und eine ganze Reihe von Eingaben.

Für einen heruntergekommenen des HotSpot-Garbage-Collector (sum, die mit Java kommt) und wie er abgestimmt ist, können Sie überprüfen this link

+0

Klingt interessant, wird es später lesen. :) – nalo

6
  • Es kompiliert auf dem Weg Programm JIT abhängt.
  • Von außen können wir nicht definitiv sagen, wann es laufen wird.
  • Es folgt ein Algorithmus, der von diesem bestimmten GC abhängt.
  • Java virtuelle Maschine läuft auf dem Client-Rechner mit etwas virtuellem Speicher im Falle von Windows-Standard ist 4 GB. Es hängt auch von diesem freien virtuellen Speicher zu dieser bestimmten Zeit ab.

Sie können dieses kleine Programm versuchen, das Verhalten von GC zu überprüfen

public class GCTest { 

    final int NELEMS = 50000; 

    void eatMemory() { 

     int[] intArray = new int[NELEMS]; 

     for (int i=0; i<NELEMS; i++) { 
     intArray[i] = i; 
     } 

    } 

    public static void main (String[] args) { 

     GCTest gct = new GCTest(); 

     // Step 1: get a Runtime object 
     Runtime r = Runtime.getRuntime(); 

     // Step 2: determine the current amount of free memory 
     long freeMem = r.freeMemory(); 
     System.out.println("free memory before creating array: " + freeMem); 

     // Step 3: consume some memory 
     gct.eatMemory(); 

     // Step 4: determine amount of memory left after consumption 
     freeMem = r.freeMemory(); 
     System.out.println("free memory after creating array: " + freeMem); 

     // Step 5: run the garbage collector, then check freeMemory 
     r.gc(); 
     freeMem = r.freeMemory(); 
     System.out.println("free memory after running gc(): " + freeMem); 
    } 
} 

möglich Ausgang -

in Ihrem Fall unterschiedlich sein kann
free memory before creating array: 4054912 
free memory after creating array: 3852496 
free memory after running gc(): 4064184 

prüfen Link http://www.devdaily.com/java/edu/pj/pj010008/

1

Die Garbage Collector wird ausgeführt, wenn Ressourcen benötigt werden, und in regelmäßigen Abständen, die Sie beeinflussen können, indem Sie angeben, wann ein gutes Timing ist e CPU ausgeben zu sammeln, System.gc()

Sie verwenden können, indem Sie Ihre Objekte init() Methoden zum Beispiel Referenzen ausdrücklich von nulling, der Garbage Collector helfen, die Ressourcen und cleanup() Methoden zuweisen, die explizit diese Ressourcen aufzuräumen und ihre Referenzen nulling. Indem Sie Referenzen selbst aufheben, verhindern Sie, dass der Müllsammler Cluster von Objekten findet, die mehr Pfade zu einer Wurzel haben.

+0

Für eine moderne gc, Variablen auf Null oder nicht setzen wird keinen Unterschied machen und Aufruf von System.gc() ist eigentlich fast immer nur dumm. – Fredrik

+2

@Fredrik, bitte verwende keine Begriffe wie "dumm". Das Festlegen von Variablen auf null ist eine gute Vorgehensweise und hilft, die Garbage Collection in kleinen Schritten statt in größeren Blöcken auszuführen. (Beachten Sie, ich spreche über Klassenattribute nicht temporäre Methodenvariablen auf dem Stapel.) Wie für den Aufruf von System.gc() müssen triviale Anwendungen nicht damit belästigen, aber große Anwendungen, die massive gleichzeitige Anforderungen erhalten manchmal brauchen es so reibungslos die Sammelzeiten halten Die Anwendung reagiert jederzeit. – rsp

+0

@rsp: Die Art, wie GCs arbeiten ist fast immer dumm oder zumindest schädlich für GC-Leistung, System.gc() zu nennen und es hilft überhaupt nicht, weshalb es a) nicht zwingend für die GC ist, sogar zu stören b) Es ist möglich, es auszuschalten, um nicht von einem Code getroffen zu werden, der von jemandem geschrieben wurde, der denkt, dass er schlauer ist als der gc-Algorithmus. Der Grund, warum es immer noch möglich ist, ist, dass es, wie ich sagte, "fast immer" dumm ist, was bedeutet, dass es ein paar Orte gibt, wo man es wirklich tun möchte. Setzen von Variablen auf null gibt Ihnen nichts als mehr Code, es wird nicht auf die GC überhaupt auswirken. – Fredrik

2

Dies hängt vollständig von der tatsächlichen JVM und was es wählt zu tun, und ist im Grunde genommen nicht in Ihre Hände als Programmierer. Greybearded hartnäckige Experten Mai wollen der JVM sagen, dass sie es besser wissen, aber für Normalsterbliche sollte dies als schwarze Magie besser in Ruhe gelassen werden.

Was Sie betreffen sollte, ist, wenn es mit der Rate Schritt halten kann, die Ihre Programme verursachen und verwirft Gegenstände. Wenn nicht, wird Ihr ganzes Programm angehalten, während die globale Bereinigung stattfindet. Das führt zu sehr schlechten Antwortzeiten, aber bei modernen JVMs auf modernen Computern passiert das selten.

Wenn Sie neugierig sind, was in Ihrem Programm passiert und wann, dann untersuchen Sie das Tool "jvisualvm" in den letzten Versionen des Java 6 JDK. Es ist wirklich großartig, ins Innere zu schauen.

0

Wenn JVM nicht über genügend Speicherplatz zum Ausführen verfügt, wird der Garbage Collector ausgeführt und löscht unnötige Objekte und weist Speicher für JVM zu.

Unnötige Objekte sind die Objekte, die keine Referenz (Adresse) dafür haben.

Es gibt hauptsächlich 4 Punkte für Objekte, die für Garbage Collector infrage kommen.

  1. Null Referenzierung

    Garbage Collector ein Objekt löschen, wenn die Referenzgröße des Objekts null zugewiesen wird, wie es Wert ist

    A a = new A(); 
        a = null; 
    
  2. Neuzuweisen

    Wenn ein anderer Objekt wird der Referenzvariablen eines Objekts zugewiesen, das ältere referenzierte Objekt kann dele sein Ted von Müll Sammler.

    A a = new A(100); 
        a =new A(200); 
    
  3. lokaler Bereich

    Wenn ein Objekt innerhalb eines Blockes erzeugt wird, der für garbage collector Anspruch Objekt wird aus der Seite dieser Blöcke.

    if(condition){ 
    
        A a = new A(); 
    
        } 
    
  4. Isolation

    Ein Objekt ein anderes Objekt beziehen können, aber es muss für garbage collector qualifizierten mindestens eine Referenz (Adresse) Variable für diese Objekte im Stapel, sonst alle diese Objekte sein.

     class A{ 
          A r; 
          A(int i){ 
          //something 
          } 
         } 
    
         A a1 = new A(100); 
         a1.r = new A(101); 
         a1.r.r = new A(102); 
         a1.r.r.r = a1; 
    
         a1 = null //all ojects are eligible to garbage collector 
    
Verwandte Themen