jvm里面年轻代,老年代,永久代,元空间

1.年轻代

年轻代主要有三个区域组成,一个是Eden区域,另一个是存活区1和存活区2。Eden主要负责对象的创建,存活区1和存活2主要负责向老年代普及对象,存活区1和存活区2这两个区域里面总存在一个是空的,为什么这两个区域里面有一个空的呢?因为这两个区域需要负责回收年轻代活跃对象,需要把这些年轻代对象晋级到老年代。Eden:存活区1:存活区2=8:1:1,这是年轻代的默认值。当然我们可以调整Eden:存活区1:存活区2参数(自己可以百度)。

2.年轻代GC实现算法

复制算法:从根集合扫描出活跃对象(说明对象也是有生命周期,那么对象的生命周期是怎样的呢?),并将存活的对象复制到一个新的未使用内存空间中(说明需要进行内存空间的分配

假设年轻代存在大量的对象,可能需要频发的产生GC,那么需要对内存空间的分配产生进行优化。

年轻代优化算法

(1)Bump-The-Pointer技术

简单理解就是每一次记住Eden最后一个对象,所以每次在创建对象时,需要检查最后一个对象,就可以知道内存是否多余的空间,这样虽然可以快速解决内存分配的问题,但是java是支持多线程的,所以我们应该这样还是有问题。

(2)TLAB(Thread-Local Allocation Buffers)

虽然上述存在多线程问题,但是使用TLAB技术将Eden分割为对个数据块,每一个数据块对应使用TLAB技术。

3.老年代

老年代就是把年轻代活跃对象放到老年代里面,但是为什么需要对堆内存进行划分?主要是因为每一次垃圾回收不用对堆内存进行全部扫描,一般的对象很少能够进入老年代,因为java是对线程,一般情况下线程的生命周期比较短。那么对象的很难存活到老年代。

4.老年代回收算法

标记--清除(Mark--Sweep):标记--清除算法主要是用根集合开始扫描,对存活对象进行标记,标记完成后,对全内存进行扫描,清除那些没有标记的对象,这样的问题是可能产生内存碎片。

标记--压缩(Mark--Compact):它的思路和标记--清除算法基本相似,只是在清除的时候,把存活的对象向左移动,并且更新引用对象的值,这样虽然可以解决内存碎片问题,但是需要的成本比较高。

5. 元区域

首先介绍元区域里面的对象是不可能进过垃圾回收的回收对象,在jdk1.8之间元区域被称为永久代,但是jdk1.8之后,永久代被元区域代替,为什么永久代会被代替?因为类的静态变量,常量,字节码被保存在永久代,32位系统默认是65m,64系统是85m,虽然可以进行参数设置,把永久代变大点,但是永久代大小不可能超过jvm大小,一旦类的元数据超过永久代大小,将会抛出OOM。

那么元区域的作用就是解决内存大小问题,元区域主要使用本机的物理内存,可以避免永久代的内存溢出问题。不过需要监控内存的消耗情况,一旦发生内存泄漏,会占用大量的本地内存。

猜你喜欢

转载自blog.csdn.net/weixin_41629878/article/details/85540445