JVM学习-----java7与Java8新生代GC发生了什么
来源:互联网 发布:新闻联播数据动画演示 编辑:程序博客网 时间:2024/04/29 12:46
测试代码
VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
verbose:gc 表示输出虚拟机中GC的详细情况.-Xms20m:表示堆的最小值为20M-Xms20m:表示堆的最大值同样设置为20M,-Xmn10M:表示新生代分配10M-XX:SurvivorRatio=8:表示新生代的eden区:from区:to区:8:1:1-XX:+PrintGCDetails 打印GC日志到控制台
package com.wuhulala.jvm.gc;/** * 新生代GC * * @author xueaohui * @version 1.0 * @date 2017/3/19 * @link https://github.com/wuhulala */public class MinorGC { private static final int _1MB = 1024 * 1024; public static void main(String[] args) { byte[] allocation1, allocation2, allocation3, allocation4; allocation1 = new byte[_1MB * 2]; allocation2 = new byte[_1MB * 2]; allocation3 = new byte[_1MB * 2]; allocation4 = new byte[_1MB * 5]; //出现一次MinorGC }}
java8_1.8.0_111
日志
/** * Heap java8 *PSYoungGen total 9216K, used 7789K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) *eden space 8192K, 95% used [0x00000000ff600000,0x00000000ffd9b7d8,0x00000000ffe00000) *from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) *to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) *ParOldGen total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) *object space 10240K, 40% used [0x00000000fec00000,0x00000000ff000010,0x00000000ff600000) *Metaspace used 3215K, capacity 4494K, committed 4864K, reserved 1056768K *class space used 355K, capacity 386K, committed 512K, reserved 1048576K */
从上面结果来看 java8 默认使用的新生代垃圾收集器是PSYoungGen(Parallel Scavenge) 它是并行收集器
注重于吞吐量的指标,吞吐量可以简单理解为 CPU执行用户程序的时间。
如果没有太多的操作 ,那么GC次数肯定也会很少,所以就不用过于关注GC的时候的停顿时间。
在这种应用场景之下,我们就可以关注一下 吞吐量了(吞吐量=运行用户代码时间/(运行用户代码时间+GC消耗的时间))
//在注释掉**allocation4 = new byte[_1MB * 4]; **此语句之后 我发现GC打印日志如下
//Heap //PSYoungGen total 9216K, used 7789K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) //eden space 8192K, 95% used [0x00000000ff600000,0x00000000ffd9b7d8,0x00000000ffe00000) //from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) //to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) //ParOldGen total 10240K, used 0K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) //object space 10240K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff600000) //Metaspace used 3216K, capacity 4494K, committed 4864K, reserved 1056768K //class space used 355K, capacity 386K, committed 512K, reserved 1048576K
可见老年代没有任何对象
在对allocation4分配内存之后
新生代内存没有发生变化 老年代的内存刚好4M内存 与allocation4的内存大小对应
那么老年代的估计就是allocation4了
但是为了解决这个疑惑
那么我为allocation4分配5M内存,查看日志
// ParOldGen total 10240K, used 5120K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
那就可以有了如下解释
PS收集器为了保证吞吐量 并且在新生代没有足够的内存的情况下 直接把新的大对象分配到了老年代
java7_1.7.0_15
/** * Heap java7 *def new generation total 9216K, used 4779K [0x331b0000, 0x33bb0000, 0x33bb0000) *eden space 8192K, 53% used [0x331b0000, 0x335ed7f0, 0x339b0000) *from space 1024K, 42% used [0x33ab0000, 0x33b1d660, 0x33bb0000) *to space 1024K, 0% used [0x339b0000, 0x339b0000, 0x33ab0000) *tenured generation total 10240K, used 6144K [0x33bb0000, 0x345b0000, 0x345b0000) *the space 10240K, 60% used [0x33bb0000, 0x341b0030, 0x341b0200, 0x345b0000) *compacting perm gen total 12288K, used 203K [0x345b0000, 0x351b0000, 0x385b0000) *the space 12288K, 1% used [0x345b0000, 0x345e2fd8, 0x345e3000, 0x351b0000) *ro space 10240K, 45% used [0x385b0000, 0x38a37290, 0x38a37400, 0x38fb0000) *rw space 12288K, 54% used [0x38fb0000, 0x3963ace8, 0x3963ae00, 0x39bb0000) */
java7 默认使用的是Serial 收集器,它是最原始的收集器。
由于survivor区没有足够的内存存放,
所以allocation1 allocation2 allocation3 直接进入老年代
在老年代的是allocation1 、allocation2、 allocation3 内存占6M
在新生代的时候是新的allocation4 内存占4M
===================2017.03.19 PM=========================
、
经查阅资料得知:
-XX:PretenureSizeThreshold 参数可以配置一个内存阀值,大于这个值的对象直接分配在老年代之中。
在Parallel Scavenge收集器中此参数无效。
那么在java7中allocation4没有进入老年代就可以解释了。
在VM参数加入
-XX:PretenureSizeThreshold=3145728 (3M)
打印日志:
Heap def new generation total 9216K, used 7348K [0x331b0000, 0x33bb0000, 0x33bb0000) eden space 8192K, 89% used [0x331b0000, 0x338dd0b8, 0x339b0000) from space 1024K, 0% used [0x339b0000, 0x339b0000, 0x33ab0000) to space 1024K, 0% used [0x33ab0000, 0x33ab0000, 0x33bb0000) tenured generation total 10240K, used 4096K [0x33bb0000, 0x345b0000, 0x345b0000) the space 10240K, 40% used [0x33bb0000, 0x33fb0010, 0x33fb0200, 0x345b0000) compacting perm gen total 12288K, used 185K [0x345b0000, 0x351b0000, 0x385b0000) the space 12288K, 1% used [0x345b0000, 0x345de658, 0x345de800, 0x351b0000) ro space 10240K, 45% used [0x385b0000, 0x38a37290, 0x38a37400, 0x38fb0000) rw space 12288K, 54% used [0x38fb0000, 0x3963ace8, 0x3963ae00, 0x39bb0000)
the space 10240K, 40% used [0x33bb0000, 0x33fb0010, 0x33fb0200, 0x345b0000)
由上可知allocation4现在在老年代中
占用了40%的内存
tip: 大内存对象最好不要用
- JVM学习-----java7与Java8新生代GC发生了什么
- Java基础学习总结(119)——Java8 JVM与Java7 JVM比较
- 【JVM】java 虚拟机--新生代与老年代GC
- JVM gc只新生代串行GC
- JVM的GC机制<一>新生代GC
- JVM的GC机制<一>新生代GC
- 通过 jstat -gcutil 来学习JVM 内存分配策略与 GC 发生时机
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- java 虚拟机--新生代与老年代GC
- 使用命令行工具构建Maven项目
- C++数据类型转换知识点
- Java
- leetcode解题之242# Valid Anagram Java版 (判断两个字母串是否具有相同的字母组合)
- 找出两个链表的第一个公共结点
- JVM学习-----java7与Java8新生代GC发生了什么
- php 表单 与数据库查询
- 三星手机摔一下,就花屏啦!!
- String
- LITTLE MUSIC PLAYER
- ArrayList和LinkedList的区别
- PAT
- 自己动手写RTP服务器——关于RTP协议
- Hibernate 框架学习