一、内存管理机制、GC回收、使用中参数配置:参考
1、java的内存模式
java中说的内存:程序执行过程中,存储程序执行期间需要用到的数据和相关信息这时所用到的空间。
先看下java执行一段程序具体的过程:
java程序执行过程
(1)java编辑器将.java文件编译成.class的字节文件
(2)类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行
运行数据的区间包括以下几部分:
运行时数据区
2、新生代到老年代回收机制:(参考)
Java中的堆也是GC 收集垃圾的主要区域。GC 分为两种:MinorGC、Full GC ( 或称为Major GC )。
MinorGC 是发生在新生代中的垃圾收集动作,所采用的是复制算法。
新生代几乎是所有Java 对象出生的地方,即 Java 对象申请的内存以及存放都是在这个地方。Java中的大部分对象通常不需长久存活,具有朝生夕灭的性质。
当一个对象被判定为"死亡" 的时候,GC就有责任来回收掉这部分对象的内存空间。新生代是GC 收集垃圾的频繁区域。
当对象在Eden ( 包括一个 Survivor 区域,这里假设是 from 区域 ) 出生后,在经过一次 Minor GC 后,如果对象还存活,并且能够被另外一块Survivor 区域所容纳( 上面已经假设为 from 区域,这里应为 to 区域,即 to 区域有足够的内存空间来存储 Eden 和 from 区域中存活的对象 ),则使用复制算法将这些仍然还存活的对象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中,然后清理所使用过的 Eden 以及 Survivor 区域 ( 即 from 区域 ),
新生代采用空闲指针的方式来控制GC触发,指针保持最后一个分配的对象在新生代区间的位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC。当连续分配对象时,对象会逐渐从eden到 survivor,最后到老年代。
但这也不是一定的,对于一些较大的对象( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代。
FullGC 是发生在老年代的垃圾收集动作,所采用的是标记-清除算法。
老年代与新生代不同,对象存活的时间比较长,比较稳定,因此采用标记(Mark)算法来进行回收,所谓标记就是扫描出存活的对象,然后再进行回收未被标记的对象,回收后对用空出的空间要么进行合并,要么标记出来便于下次进行分配,总之就是要减少内存碎片带来的效率损耗。在执行机制上JVM提供了串行GC(SerialMSC)、并行GC(parallelMSC)和并发GC(CMS),具体算法细节还有待进一步深入研究。
3、参数设置:(一些参数可参考)
新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数–XX:NewRatio 来指定)
Eden : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定)
-Xmx——设置JVM最大使用内存
-Xms——设置JVM初始内存(
此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。)
-Xmn——设置年轻代大小(整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m)
-Xss——设置每个线程的堆栈大小
4、分配担保机制( 参考)
发生条件:当在新生代无法分配内存的时候,把新生代的对象转移到老生代,然后把新对象放入腾空的新生代。
详细例子可参考上边链接,摘总结如下:
新生代内存不足时,把新生代的存活的对象搬到老生代,然后新生代腾出来的空间用于为分配给最新的对象。这里老生代是担保人。在不同的GC机制下,也就是不同垃圾回收器组合下,担保机制也略有不同。在Serial+Serial
Old的情况下,发现放不下就直接启动担保机制;在Parallel
Scavenge+Serial Old的情况下,却是先要去判断一下要分配的内存是不是>=Eden区大小的一半,如果是那么直接把该对象放入老生代,否则才会启动担保机制。










网友评论