>  기사  >  Java  >  JVM 가비지 수집 알고리즘 및 jvm 힙 메모리의 세 영역

JVM 가비지 수집 알고리즘 및 jvm 힙 메모리의 세 영역

php是最好的语言
php是最好的语言원래의
2018-07-30 11:24:371963검색

일반적인 JVM 가비지 수집 알고리즘

jdk1.7.0_79

우리 모두 알고 있듯이 Java는 프로그래머가 메모리를 수동으로 관리할 필요가 없는 언어이며 자동으로 관리하기 위해 JVM에 전적으로 의존합니다. 자동으로 관리되기 때문에 가비지 메모리 재활용 메커니즘이나 재활용 알고리즘이 있어야 합니다. 이 기사에서는 몇 가지 일반적인 가비지 수집(이하 GC) 알고리즘을 소개합니다.

  Java 힙의 인스턴스 객체에 메모리가 할당되면 가상 머신 스택의 참조 변수에 인스턴스 객체의 시작 주소가 저장됩니다.

Object obj = new Object();

 이제 변수를 null에 할당하면 됩니다.

obj = null;

이 시점에서 Java힙의 인스턴스 개체가 이를 다시 참조할 수 없다는 것을 알 수 있습니다. 그러면 해당 개체는 GCed된 개체입니다. 가상 머신 스택의 obj 변수는 어떻습니까? 앞서 "JVM 소개 - 런타임 데이터 영역"에서 언급한 것처럼 가상 머신 스택은 스레드 전용이므로 스레드가 초기화되면 가상 머신의 메모리도 초기화되고 소멸됩니다. 스택 자연스럽게 재활용됩니다. 즉, 가상 머신 스택의 메모리 공간이 가상 머신 GC 범위 내에 있지 않음을 의미합니다. 다음 그림은 가비지 컬렉션의 메모리 범위를 보여줍니다.

 1.객체가 "죽은" 알고리즘입니까 - 참조 카운터 알고리즘

 참조 카운터가 객체에 추가됩니다. 다른 곳에서 인용할 수 없다는 뜻입니다. 로컬 참조가 있으면 +1, 참조가 유효하지 않으면 -1이 됩니다. 재미있고 간단한 알고리즘처럼 보이지만 실제로 이 알고리즘은 객체 순환 참조라는 치명적인 문제를 야기하기 때문에 대부분의 Java 가상 머신에서 사용되지 않습니다. 객체 A는 B를 가리키고, 객체 B는 차례로 A를 가리킵니다. 이때 그들의 참조 카운터는 0이 아니지만 둘 다 자신을 가리키는 것이 없기 때문에 사실상 의미가 없습니다. 그래서 다음과 같은 알고리즘이 도입됩니다.

 

 2.

객체가 "죽은" 알고리즘인가 - 도달성 분석 알고리즘 이 알고리즘은 객체 순환 참조 상황 전체를 트리로 표현하고 루트 노드를 효과적으로 피할 수 있습니다. 이 개체에서 "GC Roots"라는 개체가 시작되어 아래쪽으로 검색되어 표시되고 트리를 순회한 후 표시되지 않은 개체는 "죽음"으로 판단되어 재활용될 수 있습니다.

GC 알고리즘

1. Mark-clear 알고리즘

재활용할 객체의 "마킹" 과정을 기다리는 것은 위에서 언급한 바와 같습니다. 또 다른 새로운 문제가 발생합니다 - 메모리 조각화. 더 큰 개체 인스턴스가 다음에 힙에 더 큰 메모리 공간을 할당해야 하는 경우 충분한 연속 메모리를 찾는 것이 불가능할 수 있으며 가비지 수집이 다시 트리거되어야 합니다.

 2.

복사 알고리즘

(Java 힙의 차세대 가비지 수집 알고리즘)이 GC 알고리즘은 마크 클리어 알고리즘으로 인해 발생하는 "메모리 조각화" 문제를 실제로 해결합니다. 먼저 재활용할 메모리와 재활용할 필요가 없는 메모리를 표시하고, 다음 단계는 재활용할 필요가 없는 메모리를 새로운 메모리 영역에 복사하여 기존 메모리 영역을 완전히 재활용할 수 있도록 하는 것이다. , 새로운 메모리 영역은 연속적입니다. 단점은 복사를 위해 항상 일부 메모리를 확보해야 하기 때문에 일부 시스템 메모리가 손실된다는 것입니다.

  앞서 "JVM 소개 - 런타임 데이터 영역"에서 언급한 것처럼 Java 힙은 신세대와 구세대로 구분됩니다. 이 구분은 GC를 용이하게 하기 위한 것입니다. Java 힙의 새로운 세대는 GC 복사 알고리즘을 사용합니다. 새로운 세대는 Eden 공간, To Survivor 공간, From Survivor 공간의 세 영역으로 나누어지며, 하나는 비어 있음이 보장됩니다. 이 그림의 왼쪽에 있는 새로운 세대 부분에 주의를 돌리는 것이 좋습니다.

새로운 개체 인스턴스가 생성되면 일반적으로 Eden 공간에서 발생하는 GC는 다음과 같습니다. Minor GC라고 합니다. GC가 발생한 후

는 Eden

의 메모리와 Survivor 공간 중 하나를 다른 Survivor에 복사합니다. 구세대로 이동합니다. 에덴은 새로운 세대의 대다수를 차지하는 반면, 두 생존자는 실제로 아주 작은 부분을 차지한다는 것을 알 수 있습니다. 이는 대부분의 개체가 생성된 직후에 GC되기 때문입니다(여기서는 80/20 원칙이 사용될 수 있음).

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

如图:

JVM 가비지 수집 알고리즘 및 jvm 힙 메모리의 세 영역

  • 一.年轻代

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

JVM 가비지 수집 알고리즘 및 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对象也会被回收。

相关文章:

jvm 가비지 수집 알고리즘

Java 가비지 수집 및 개체 수명 주기에 대한 자세한 설명

관련 동영상:

javascript 초보자 튜토리얼

위 내용은 JVM 가비지 수집 알고리즘 및 jvm 힙 메모리의 세 영역의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.