jdk1.7.0_79
Wie wir Wie wir alle wissen, ist Java eine Sprache, die keine manuelle Speicherverwaltung durch Programmierer erfordert. Da sie automatisch verwaltet wird, muss ein Garbage-Memory-Recycling-Mechanismus oder -Algorithmus vorhanden sein. In diesem Artikel werden mehrere gängige Garbage-Collection-Algorithmen (im Folgenden als GC bezeichnet) vorgestellt.
Wenn einem Instanzobjekt auf dem Java-Heap Speicher zugewiesen wird, speichert die Referenzvariable im Stapel der virtuellen Maschine die Startadresse des Instanzobjekts.
Object obj = new Object();
Wenn wir nun die Variable auf Null zuweisen.
obj = null;
An diesem Punkt können Sie sehen, dass das Instanzobjekt auf dem Java-Heap nicht erneut darauf verweisen kann, dann handelt es sich um ein Objekt, das GCed wurde es ist das Objekt „ist gestorben“. Was ist mit der obj-Variablen auf dem Stapel der virtuellen Maschine? Wie oben in „Einführung in JVM – Laufzeitdatenbereich“ erwähnt, ist der Stapel der virtuellen Maschine exklusiv für den Thread, was bedeutet, dass er initialisiert wird und stirbt, wenn der Thread initialisiert wird, der Speicher auf der virtuellen Maschine Stapel Es wird natürlich recycelt, was bedeutet, dass dieser Speicherplatz auf dem Stapel der virtuellen Maschine nicht im Bereich des GC der virtuellen Maschine liegt . Die folgende Abbildung zeigt den Speicherbereich der Garbage Collection:
1. Ob das Objekt „tot“ ist Algorithmus – Referenzzähleralgorithmus
Fügen Sie dem Objekt einen Referenzzähler hinzu. Wenn der Referenzzähler 0 ist, bedeutet dies, dass keine andere Stelle darauf verweist. Wenn eine lokale Referenz vorhanden ist, +1, und wenn die Referenz ungültig ist, -1. Es scheint ein lustiger und einfacher Algorithmus zu sein, aber tatsächlich wird dieser Algorithmus in den meisten virtuellen Java-Maschinen nicht verwendet, da er ein schwerwiegendes Problem mit sich bringt – den Objektzirkelverweis. Objekt A zeigt auf B und Objekt B zeigt wiederum auf A. Zu diesem Zeitpunkt sind ihre Referenzzähler nicht 0, aber beide sind tatsächlich bedeutungslos, da nichts auf sie zeigt. Daher wird der folgende Algorithmus eingeführt.
2. Ob das Objekt „tot“ ist Algorithmus – Erreichbarkeitsanalysealgorithmus
Dieser Algorithmus kann das effektiv vermeiden Die gesamte Objektinstanz wird als Baum dargestellt. Suchen Sie von diesem Objekt aus nach unten und markieren Sie es wird als „tot“ beurteilt, d. h. es kann recycelt werden.
GC-Algorithmus
1.Mark-Sweep-Algorithmus
Warten darauf recycelt Der „Markierungs“-Prozess von Objekten wurde oben erwähnt. Wenn das Objekt direkt nach der Markierung gelöscht wird, entsteht ein weiteres neues Problem – die Speicherfragmentierung. Wenn beim nächsten Mal eine größere Objektinstanz einen größeren Speicherplatz auf dem Heap zuweisen muss, ist es möglicherweise nicht möglich, genügend zusammenhängenden Speicher zu finden und die Garbage Collection muss erneut ausgelöst werden.
2.Kopieralgorithmus (Garbage-Collection-Algorithmus für die neue Generation im Java-Heap)
Dieser GC-Algorithmus löst tatsächlich den Mark-Sweep-Algorithmus Das Problem der „Speicherfragmentierung“, verursacht durch. Markieren Sie zunächst den Speicher, der recycelt werden soll, und den Speicher, der nicht recycelt werden muss. Der nächste Schritt besteht darin, den Speicher, der nicht recycelt werden muss, in den neuen Speicherbereich zu kopieren, damit der alte Speicherbereich vollständig recycelt werden kann , und der neue Speicherbereich ist kontinuierlich. Der Nachteil besteht darin, dass etwas Systemspeicher verloren geht, da Sie zum Kopieren immer etwas Speicher freigeben müssen.
Wie oben in „Einführung in JVM – Laufzeitdatenbereich“ erwähnt, ist der Java-Heap in die neue Generation und die alte Generation unterteilt. Diese Aufteilung dient der Erleichterung der GC. Die neue Generation im Java-Heap verwendet den GC-Kopieralgorithmus. Die neue Generation ist in drei Bereiche unterteilt: Eden-Raum, To-Survivor-Raum und From-Survivor-Raum. Von-Survivor und To-Survivor sind gleich groß, und einer ist garantiert leer. Sie können Ihre Aufmerksamkeit genauso gut auf den Teil der neuen Generation auf der linken Seite dieses Bildes richten:
Wenn eine neue Objektinstanz erstellt wird, befindet sie sich normalerweise im Eden-Raum . GC heißt Minor GC. Wenn ein GC in der neuen Generation auftritt, kopiert die Erinnerung an Eden und einen der Survivor-Räume ein weiteres In Survivor wird das Speicherobjekt in die alte Generation verschoben, wenn ein Objekt mehrere Male überlebt. Es ist ersichtlich, dass Eden den Großteil der neuen Generation ausmacht, während die beiden Überlebenden tatsächlich einen sehr kleinen Teil ausmachen. Dies liegt daran, dass die meisten Objekte kurz nach ihrer Erstellung einem GC unterzogen werden (hier kann das 80/20-Prinzip verwendet werden).
3.标记-压缩算法(或称为标记-整理算法,Java堆中老年代的垃圾回收算法)
对于新生代,大部分对象都不会存活,所以在新生代中使用复制算法较为高效,而对于老年代来讲,大部分对象可能会继续存活下去,如果此时还是利用复制算法,效率则会降低。标记-压缩算法首先还是“标记”,标记过后,将不用回收的内存对象压缩到内存一端,此时即可直接清除边界处的内存,这样就能避免复制算法带来的效率问题,同时也能避免内存碎片化的问题。老年代的垃圾回收称为“Major GC”。
不积跬步,无以至千里;不积小流,无以成江海。
1.JVM的堆栈
栈:在jvm中栈用来存储一些对象的引用、局部变量以及计算过程的中间数据,在方法退出后那么这些变量也会被销毁。它的存储比堆快得多,只比CPU里的寄存器慢
堆:用来存储程序中的一些对象,比如你用new关键字创建的对象,它就会被存储在堆内存中,但是这个对象在堆内存中的首地址会存储在栈中。
栈内存在JVM中默认是1M,可以通过下面的参数进行设置
-Xss
1
最小堆内存在JVM中默认物理内存的64分之1,最大堆内存在JVM中默认物理内存4分之一,且建议最大堆内存不大于4G,并且设置-Xms=-Xmx避免每次GC后,调整堆的大小,减少系统内存分配开销
-Xms -Xmx
1
2
3
在jvm的堆内存中有三个区域:
1.年轻代:用于存放新产生的对象。
2.老年代:用于存放被长期引用的对象。
3.持久带:用于存放Class,method元信息。
如图:
一.年轻代
年轻代中包含两个区:Eden 和survivor,并且用于存储新产生的对象,其中有两个survivor区如图:
可以使用参数配置年轻代的大小,如果配置它为100M那么就相当于2*survivor+Eden = 100M
-Xmn
1
可以配置Eden 和survivor区的大小,这里配置的是比值,jvm中默认为8,意思就是Eden区的内存比上survivor的内存等于8,如果年轻代的Xmn配置的100M,那么Eden就会被分配80M内存,每个survivor分配10M内存
-XX:SurvivorRatio
1
还可以配置年轻代和老年代的比值,这里需要注意:老年代的内存就是通过这个比值设置,jvm没有给你直接设置老年代内存大小的参数;如果整个堆内存设为100M并且在这里设置年轻代和老年代的比值为7,如果持久代占用了10M,那么100M-10M=90M这里的90M就是老年代和年轻代的内存总和,且年轻代占用(90/(7+1)*7)的内存,老年代就占用(90/(7+1)*1)的内存。
-XX:NewRatio
1
二.老年代
年轻代在垃圾回收多次都没有被GC回收的时候就会被放到老年代,以及一些大的对象(比如缓存,这里的缓存是弱引用),这些大对象可以不进入年轻代就直接进入老年代(1.防止新生代有大量剩余的空间,而大对象创建导致提前发生GC;2.防止在eden区和survivor区的大对象复制造成性能问题),这个可以通过如下参数设置,表示单个对象超过了这个值就会直接到老年带(默认为0):
-XX:PretenureSizeThreshold
1
并且大的数组对象也会直接放到老年代,比如array和arrayList(底层用数组实现),因为数组需要连续的空间存储数据。
三.持久代
持久代用来存储class,method元信息,大小配置和项目规模,类和方法的数量有关,一般配置128M就够了,设置原则是预留30%空间,它可以通过如下参数进行大小配置:
-XX: PermSize -XX: MaxPermSize
1
2
持久代也可能会被GC回收,如果持久代理的常量池没有被引用以及一些无用的类信息和类的Class对象也会被回收。
相关文章:
JVM-Garbage-Collection-Algorithmus
Detaillierte Java-Erklärung der Garbage Collection und des Objektlebenszyklus
Ähnliche Videos:
Das obige ist der detaillierte Inhalt vonJVM-Garbage-Collection-Algorithmus und drei Bereiche im Heap-Speicher von JVM. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!