Maison  >  Article  >  Java  >  Algorithme de récupération de place JVM et trois zones dans la mémoire tas de JVM

Algorithme de récupération de place JVM et trois zones dans la mémoire tas de JVM

php是最好的语言
php是最好的语言original
2018-07-30 11:24:372009parcourir

Algorithmes communs de collecte des ordures JVM

jdk1.7.0_79

Comme nous tout le monde le sait, Java est un langage qui n'exige pas que les programmeurs gèrent manuellement la mémoire. Il s'appuie entièrement sur la JVM pour gérer automatiquement la mémoire, car elle est gérée automatiquement, il doit y avoir un mécanisme ou un algorithme de recyclage de la mémoire inutile. Cet article présentera plusieurs algorithmes courants de garbage collection (ci-après dénommés GC).

Lorsqu'une mémoire est allouée à un objet instance sur le tas Java, la variable de référence sur la pile de la machine virtuelle stockera l'adresse de départ de l'objet instance.

Object obj = new Object();

Maintenant, si nous attribuons la variable à null.

obj = null;

À ce stade, vous pouvez voir que l'objet instance sur le tas Java ne peut pas le référencer à nouveau, alors c'est un objet qui a été GCed, nous l'appelons un objet "Mort" . Qu’en est-il de la variable obj sur la pile de machines virtuelles ? Comme mentionné ci-dessus dans "Introduction à JVM - Zone de données d'exécution", la pile de machine virtuelle est exclusive au thread, ce qui signifie qu'elle est initialisée et meurt au fur et à mesure de l'initialisation du thread. Lorsque le thread est détruit, la mémoire de la machine virtuelle. pile Il sera naturellement recyclé, ce qui signifie cet espace mémoire sur la pile de la machine virtuelle n'est pas dans la portée du GC de la machine virtuelle . La figure suivante montre la plage de mémoire du garbage collection :

 1. Si l'objet est un algorithme "mort" - algorithme de compteur de référence

Ajoutez un compteur de référence à l'objet. Si le compteur de référence est à 0, cela signifie qu'aucun autre endroit ne le référence. S'il existe une référence locale, +1, et si la référence n'est pas valide, -1. Cela semble être un algorithme simple et amusant, mais en fait, cet algorithme n'est pas utilisé dans la plupart des machines virtuelles Java car il entraînerait un problème fatal : la référence circulaire d'objet. L'objet A pointe vers B, et l'objet B pointe à son tour vers A. À ce stade, leurs compteurs de référence ne sont pas 0, mais les deux n'ont en réalité aucun sens car rien ne les pointe. L’algorithme suivant est donc introduit.

  2. Si l'objet est un algorithme "mort" - Algorithme d'analyse d'accessibilité

Cet algorithme peut efficacement éviter le Situation de référence circulaire d'objet.L'instance entière de l'objet est présentée comme un arbre.Le nœud racine est un objet appelé "GC Roots". À partir de cet objet, recherchez vers le bas et marquez-le. sera jugé « mort », c'est-à-dire qu'il peut être recyclé.

Algorithme GC

 1.Algorithme de balayage de marque

En attente d'être recyclé Le processus de « marquage » des objets a été mentionné ci-dessus. Si l'objet est effacé directement après avoir été marqué, un autre nouveau problème surviendra : la fragmentation de la mémoire. Si une instance d'objet plus grande doit allouer un espace mémoire plus grand sur le tas la prochaine fois, il se peut qu'il ne soit pas possible de trouver suffisamment de mémoire contiguë et le garbage collection devra être déclenché à nouveau.

 2.Algorithme de copie (Algorithme de récupération de place pour la nouvelle génération dans le tas Java)

Cet algorithme GC résout en fait l'algorithme de balayage de marque Le problème de « fragmentation de la mémoire » causé par. Tout d'abord, marquez la mémoire à recycler et la mémoire qui n'a pas besoin d'être recyclée. L'étape suivante consiste à copier la mémoire qui n'a pas besoin d'être recyclée dans la nouvelle zone mémoire, afin que l'ancienne zone mémoire puisse être entièrement recyclée. , et la nouvelle zone mémoire est continue. Son inconvénient est qu'il perdra de la mémoire système, car vous devrez toujours libérer de la mémoire pour la copie.

Comme mentionné ci-dessus dans "Introduction à JVM - Runtime Data Area", le tas Java est divisé en la nouvelle génération et l'ancienne génération. Cette division est destinée à faciliter le GC. La nouvelle génération du tas Java utilise l'algorithme de copie GC. La nouvelle génération est divisée en trois zones : l'espace Eden, l'espace To Survivor et l'espace From Survivor et From Survivor et to Survivor ont la même taille, et l'une est garantie d'être vide. Autant reporter votre attention sur la partie nouvelle génération sur le côté gauche de cette image :

Lorsqu'une nouvelle instance d'objet est créée, elle se trouve généralement dans l'espace Eden GC est appelé Minor GC Lorsqu'un GC se produit dans la nouvelle génération, copiera la mémoire d'Eden et l'un des espaces Survivant dans. un autre Dans Survivor , si un objet survit plusieurs fois, l'objet mémoire sera déplacé vers l'ancienne génération. On constate qu'Eden représente la majorité de la nouvelle génération, alors que les deux Survivants n'en représentent en réalité qu'une très petite partie. En effet, la plupart des objets seront GCés peu de temps après leur création (le principe 80/20 peut être utilisé ici).

  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元信息。

如图:

Algorithme de récupération de place JVM et trois zones dans la mémoire tas de JVM

  • 一.年轻代

年轻代中包含两个区:Eden 和survivor,并且用于存储新产生的对象,其中有两个survivor区如图:

Algorithme de récupération de place JVM et trois zones dans la mémoire tas de JVM

可以使用参数配置年轻代的大小,如果配置它为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对象也会被回收。

相关文章:

Algorithme de collecte des ordures jvm

Explication détaillée Java de la collecte des ordures et du cycle de vie des objets

Vidéos associées :

Tutoriel Javascript débutant

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn