JVM内存与GC

你对JVM内存组成结构和JVM垃圾回收机制是否熟悉,这里和大家简单分享一下,希望对你的学习有所帮助,首先来看一下JVM内存结构,它是由堆、栈、本地方法栈、方法区等部分组成,结构图如下所示。

JVM学习笔记 JVM内存管理和JVM垃圾回收

JVM内存组成结构

JVM内存结构由堆、栈、本地方法栈、方法区等部分组成,结构图如下所示:

JVM内存管理和JVM垃圾回收机制 - Gui Xun Long - Hello Java

 1)堆

所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。堆被划分为新生代和旧生代,新生代又被进一步划分为Eden和Survivor区,最后Survivor由FromSpace和ToSpace组成,结构图如下所示:

JVM内存管理和JVM垃圾回收机制 - Gui Xun Long - Hello Java

 新生代。新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例旧生代。用于存放新生代中经过多次垃圾回收仍然存活的对象

2)栈

每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果

3)本地方法栈

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

4)方法区

存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。JVM用持久代(PermanetGeneration)来存放方法区,可通过-XX:PermSize和-XX:MaxPermSize来指定最小值和最大值。介绍完了JVM内存组成结构,下面我们再来看一下JVM垃圾回收机制。

JVM垃圾回收机制

JVM分别对新生代和旧生代采用不同的垃圾回收机制

新生代的GC:

新生代通常存活时间较短,因此基于Copying算法来进行回收,所谓Copying算法就是扫描出存活的对象,并复制到一块新的完全未使用的空间中,对应于新生代,就是在Eden和FromSpace或ToSpace之间copy。新生代采用空闲指针的方式来控制GC触发,指针保持最后一个分配的对象在新生代区间的位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC。当连续分配对象时,对象会逐渐从eden到 survivor,最后到旧生代,

用javavisualVM来查看,能明显观察到新生代满了后,会把对象转移到旧生代,然后清空继续装载,当旧生代也满了后,就会报outofmemory的异常,如下图所示:

JVM内存管理和JVM垃圾回收机制 - Gui Xun Long - Hello Java

 
在执行机制上JVM提供了串行GC(SerialGC)、并行回收GC(ParallelScavenge)和并行GC(ParNew)

1)串行GC

在整个扫描和复制过程采用单线程的方式来进行,适用于单CPU、新生代空间较小及对暂停时间要求不是非常高的应用上,是client级别默认的GC方式,可以通过-XX:+UseSerialGC来强制指定

2)并行回收GC

在整个扫描和复制过程采用多线程的方式来进行,适用于多CPU、对暂停时间要求较短的应用上,是server级别默认采用的GC方式,可用-XX:+UseParallelGC来强制指定,用-XX:ParallelGCThreads=4来指定线程数

3)并行GC

与旧生代的并发GC配合使用

旧生代的GC:

旧生代与新生代不同,对象存活的时间比较长,比较稳定,因此采用标记(Mark)算法来进行回收,所谓标记就是扫描出存活的对象,然后再进行回收未被标记的对象,回收后对用空出的空间要么进行合并,要么标记出来便于下次进行分配,总之就是要减少内存碎片带来的效率损耗。在执行机制上JVM提供了串行 GC(SerialMSC)、并行GC(parallelMSC)和并发GC(CMS),具体算法细节还有待进一步深入研究。

以上各种GC机制是需要组合使用的,指定方式由下表所示:

JVM内存管理和JVM垃圾回收机制 - Gui Xun Long - Hello Java

垃圾收集器

         java虚拟机的堆中存放着正在运行的java程序创建的所有对象,使用new、newarray、anewarray、multianewarray指令来创建对象。垃圾收集就是自动释放不再被程序所使用的对象的过程。

         垃圾收集算法必须做的两件事检测出垃圾对象;回收垃圾对象所使用的堆空间并还给程序。

         任何被根对象引用的的对象都是可触及的,从而是活动的;任何被活动的对象引用的对象都是可触及的。程序可以访问任何可触及的对象,所以这些对象需要保存在堆中,任何不可触及的对象都可以被收集。

 

         引用计数收集器

         堆中每一个对象都有一个引用计数。当对象被创建并且指向该对象的引用被分配给一个变量,这个对象的引用计数被置为1。当任何其他变量被赋值为对这个对象的引用时,计数加1。当一个对象的引用超过了生存期或者被置为一个新值时,对象的引用计数减1。任何引用计数为0的对象可以被当作垃圾收集。当一个对象被当作垃圾收集的时候,它引用的任何对象计数值减1。一个对象被垃圾收集之后可能导致后续其他对象的垃圾收集行动。

         优点:可以很快的执行,对于程序不能被长时间打断的实时环境很有利

         缺点:无法检测出循环引用的两个垃圾对象;每次引用计数的增加或减少都带来额外的开销。

 

         跟踪收集器

         追踪从根节点开始的对象引用图。追踪过程中遇到的对象以某种方式打上标记,当追踪结束时,未被标记的对象可被收集。

         标记阶段:垃圾收集器遍历引用树,标记每一个对象

         清除阶段:释放未被标记的对象,使用的内存被返回到正在执行的程序

 

         压缩收集器

         压缩和拷贝:快速移动对象来减少堆碎块。压缩收集器把活动的对象越过空闲区滑动到堆的一端,使堆的另一端出现一个大的连续空闲区。所有被移动的对象的引用也被更新,指向新的位置。

 

         拷贝收集器

         把所有活动的对象移动到一个新的区域,过程中对象被紧挨着布置。“停止并拷贝”:将堆分为两部分,过程中将活动的对象拷贝到未使用的堆区,缺点是需要两倍大小的内存。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值