JVM内存结构和垃圾回收机制

JVM内存结构包括程序计数器、虚拟机、本地方法栈、堆、方法区。

1.程序技术器

占用很少的内存,取下一条执行的指令。

2.虚拟机栈

保存基础数据类型和对象引用,当前线程执行每个方法的时候会在栈上申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用来存放本地方法调用过程中的临时变量,参数和结果。

3.本地方法栈

用于支持native方法的执行,存储了每个native方法调用的状态。

4.堆

保存类的实例,所有new出来的对象内存都在堆中分配,可以通过-Xms和-Xmx来分配,堆又被划分为新生代(YoungGeneration)和老年代(OldGeneration),新生代又分为Eden区和Survivor区,新new的对象都在新生代分配,Eden空间不足时,会把存在的对象移到Survivor,新生代可用-Xmn控制内存大小,也可用-XX:SurvivorRatio来控制Eden和Survivor的比例。老年代用来存放多次垃圾收集仍然存活的对象。

5.方法区 

存放了要加载的类信息、静态变量、常量、属性和方法信息。在JVM也叫永久代(PermanetGeneration),可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。

JVM垃圾回收机制

GC 分为两种:Minor GC、FullGC ( 或称为 Major GC )。

MinorGC是发生在新生代中的垃圾回收动作,采用的是复制清除算法。

新生代包含Eden和ToSurvivor 和FromSurvivor(),比例为8:1:1,JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块Survivor 区域是空闲着的。

当对象在 Eden ( 包括一个 Survivor 区域,这里假设是 from 区域 ) 出生后,在经过一次 Minor GC 后,如

果对象还存活,并且能够被另外一块 Survivor 区域所容纳( 上面已经假设为 from 区域,这里应为 to 区域,

即 to 区域有足够的内存空间来存储 Eden 和 from 区域中存活的对象 ),则使用复制算法将这些仍然还存活的对

象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中,然后清理所使用过的 Eden 以及 Survivor 区域 ( 即

from 区域 ),并且将这些对象的年龄设置为1,以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年

龄 + 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来设定

 ),这些对象就会成为老年代。

 但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代

Full GC 是发生在老年代的垃圾收集动作,所采用的是标记-清除算法

   现实的生活中,老年代的人通常会比新生代的人"早死"。堆内存中的老年代(Old)不同于这个,老年代里面的对象

几乎个个都是在 Survivor 区域中熬过来的,它们是不会那么容易就 "死掉" 了的。因此,Full GC 发生的次数不

会有 Minor GC 那么频繁,并且做一次 Full GC 要比进行一次 Minor GC 的时间更长。

另外,标记-清除算法收集垃圾的时候会产生许多的内存碎片 ( 即不连续的内存空间 ),此后需要为较大的对象

分配内存空间时,若无法找到足够的连续的内存空间,就会提前触发一次 GC 的收集动作。

 

永久代
指内存的永久保存区域,主要存放Class和Meta(元数据)的信息,Class在被加载的时候被放入永久区域. 它和存放实例的区域不同,GC不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的Class的增多而胀满,最终抛出Out of Memory异常。 
在Java8中,永久代已经被移除,被一个称为“元数据区”(元空间)的区域所取代。 
元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入 native memory, 字符串池和类的静态变量放入java堆中. 这样可以加载多少类的元数据就不再由MaxPermSize控制, 而由系统的实际可用空间来控制. 
采用元空间而不用永久代的几点原因: 
1、为了解决永久代的Out of Memory问题,元数据和class对象存在永久代中,容易出现性能问题和内存溢出。 
2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出(因为堆空间有限,此消彼长)。 
3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。 
4、Oracle 可能会将HotSpot 与 JRockit 合二为一。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值