jvm垃圾回收机制
jvm内存回收总是在逻辑堆中回收的,只有堆中的内容是动态申请分配的。
垃圾回收机制简称为GC,他就是标记所有活着的实例,将没有标记的实例全部回收,释放内存。
jvm内存运行的重要区域主要有:
1.堆(heap)是最大的一块区域,用于存放对象实例和数组,是全局共享的;
2.栈(stack)全称为虚拟机栈,主要存放基本数据类型,对象的引用,私有线程;
3.方法区域(method area)class被加载后的一些信息,静态常量,常量放在这里,被称为永生代。
逻辑堆中分为年轻代和年老代,年轻代分为三个区:一个Eden区,两个survivor区。大部分对象在Eden区产生,当Eden区满了之后,将还存活的对象复制到一个survivor区,当其中一个survivor区满了之后,再将还存活的对象复制到另一个survivor区。当这个survivor区也满了之后,就将从第一个survivor区复制过来还存活的对象,复制到年老代。
年轻代:
年轻代中jvm用的是Mark-copy算法,第一步是先标记,第二步是复制。Mark主要是标记还存活的实例,清除没有标记的实例,释放内存,然后copy是将还活着的实例根据年龄复制到不同的年龄代。怎么区分这个年龄代?一般是用引用计数器,每个实例中都有一个引用计数器,当这个对象被调用的时候,引用计数器就+1,不引用就-1。
当我们new一个对象时,就会向逻辑堆申请内存,当内存不足时,就会触发GC,每个实例都有一个年龄,当引用经历一次GC时,年龄就会+1,同时将没有清除的对象copy到年轻代中的survivor1区中
当第二次GC执行的时候,就会触发Mark算法找到存活的对象,将他们的年龄+1,将他们copy到survivor2区中,执行GC,就可以实现survivor1与survivor2两个区交互使用。
当对象年龄足够大时,对象就移到年老代中,(这里移到年老代中的标准是jvm参数决定的)。
年老代:
当GC 触发的时候,年轻代中的survivor2区也容不下的时候,就会转移到年轻代中的Tenured区,当这个区也容不下的时候,就会自动转到年老代中,在转移到年老代中的时候,会触发年老代中的GC ,再将转移过来的对象发到年老代中。
年老代中的GC算法:Parallel Scavenge,简称为PS算法,ps算法执行的是Mark-copy算法,和年轻代中的一样,但是compat算法将年老代的对象进行碎片化的整理。
还没有评论,来说两句吧...