美文网首页
Java虚拟机学习(二)

Java虚拟机学习(二)

作者: 今年五年级 | 来源:发表于2019-10-15 09:30 被阅读0次

    老年代

    这些位于老年代的经典对象有:\color{red}{数据库连接池}\color{red}{静态变量},有很多,只要程序一直运行,一直有指针指向他,他就是属于老不死的对象

    测试查看GC过程

    public class HeapTest {
        //100KB
        byte[] b = new byte[1024*100];
    
        public static void main(String[] args) throws InterruptedException {
            ArrayList<HeapTest> heapTests = new ArrayList<>();
            while(true){
                heapTests.add(new HeapTest());
                Thread.sleep(50);
            }
        }
    }
    

    这个字节数组占用的内存是100KB,也就是这个对象一旦new出来,至少占内存空间是大于100KB的
    下面代码不断创建对象,放到list中,这个程序一直执行,会产生大量新的对象,同时是被list指向的,是有用的,是不会被minorGC回收掉的,程序不断执行,最终将会导致内存溢出

    使用jvisualvm(jdk自带的命令)监控,cmd窗口直接执行jvisualvm命令,将启动该程序,Jvisualvm会自动寻找本机的所有java进程

    启动刚才的程序heapTest

    图片.png

    双击我们的heapTest程序,选择visual GC,查看GC过程动态图


    gc2.gif 图片.png

    新new出来的对象位于eden区域,所以eden区域一直在增长,一开始是0的,随着程序的运行,慢慢的增长,然后降到最低然后又增长

    增长到峰值的时候,伊甸园区满了,就会马上做一次GC,就会在GC时间图上打印一条峰值标识,然后就会马上把伊甸园区的内存释放掉,这时候伊甸园区又回到初始位置


    图片.png

    同时把一部分有用的对象挪移到survivor0区域,当survivor0区域满了以后,又会进行一次GC,清理无效对象,剩余有效对象一次全部挪移到survivor1区域,然后反复,可以看到是交叉的


    图片.png

    可以看到old区是一会平稳然后突然内存占用上一个台阶,继续平稳,
    这部分平稳的区域正好是survivor区经历了15次minor GC,他才可能突然把一堆对象加到old区


    图片.png

    元空间即方法区的内存在程序运行的时候是不动的,但是在程序刚开始运行,加载程序的时候,他的内存是一下增长到最高点的,因为在加载类

    图片.png

    Old区放满以后会出现什么事情?
    答案:程序已经奔溃了,oom:heap space
    原因:当old区满以后,底层会触发Full GC,将会对老年代的垃圾进行收集,但是当他收集的时候发现,老年代里面的对象都是有用的,那么GC不会释放任何东西,这样,再往老年代放东西,就会出现空间不够用的情况,即OOM

    虚拟机调优初步

    一般用的垃圾收集器是G1收集器,每秒几十万并发的系统会频繁发生Full GC

    Java虚拟机调优的目的是什么?
    Full gc是一个非常慢的过程,java虚拟机在执行full GC的时候,很多情况下会出现
    Stop the world,即停掉我们应用程序(应用线程)的执行,即会让我们应用程序卡住,影响我们程序的执行

    因此,java虚拟机调优的目的是为了减少Full GC的次数,出现的越少越好
    同时,减少一次Full GC的时间,因为full GC的时间越长,stop the world的时间就越长,应用程序卡死的时间就越长
    怎么调优?
    通过观察他的调优日志

    图片.png
    如果为idea,通过如下方式配置打印GC日志
    -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:./gc.log
    图片.png
    Java HotSpot(TM) 64-Bit Server VM (25.171-b11) for windows-amd64 JRE (1.8.0_171-b11), built on Mar 28 2018 16:06:12 by "java_re" with MS VC++ 10.0 (VS2010)
    Memory: 4k page, physical 8263504k(2346828k free), swap 16652112k(6491288k free)
    CommandLine flags: -XX:InitialHeapSize=132216064 -XX:MaxHeapSize=2115457024 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 
    2019-10-15T10:27:29.145+0800: 14.641: [GC (Allocation Failure) [PSYoungGen: 33211K->5116K(38400K)] 33211K->28718K(125952K), 0.0187916 secs] [Times: user=0.02 sys=0.05, real=0.02 secs] 
    2019-10-15T10:27:45.962+0800: 31.456: [GC (Allocation Failure) [PSYoungGen: 38339K->5084K(38400K)] 61941K->61199K(125952K), 0.0184338 secs] [Times: user=0.00 sys=0.02, real=0.02 secs] 
    2019-10-15T10:27:45.979+0800: 31.475: [Full GC (Ergonomics) [PSYoungGen: 5084K->0K(38400K)] [ParOldGen: 56115K->60903K(129024K)] 61199K->60903K(167424K), [Metaspace: 3964K->3964K(1056768K)], 0.0167096 secs] [Times: user=0.03 sys=0.00, real=0.02 secs] 
    2019-10-15T10:28:02.924+0800: 48.419: [GC (Allocation Failure) [PSYoungGen: 33189K->5028K(38400K)] 94093K->93836K(167424K), 0.0237348 secs] [Times: user=0.02 sys=0.11, real=0.02 secs] 
    2019-10-15T10:28:20.109+0800: 65.604: [GC (Allocation Failure) [PSYoungGen: 38283K->5096K(38400K)] 127091K->127017K(167424K), 0.0119623 secs] [Times: user=0.03 sys=0.02, real=0.01 secs] 
    2019-10-15T10:28:20.121+0800: 65.616: [Full GC (Ergonomics) [PSYoungGen: 5096K->0K(38400K)] [ParOldGen: 121920K->126915K(196096K)] 127017K->126915K(234496K), [Metaspace: 3964K->3964K(1056768K)], 0.0333172 secs] [Times: user=0.06 sys=0.00, real=0.03 secs] 
    2019-10-15T10:28:37.102+0800: 82.597: [GC (Allocation Failure) [PSYoungGen: 33260K->5028K(37888K)] 160175K->160248K(233984K), 0.0248040 secs] [Times: user=0.03 sys=0.03, real=0.03 secs] 
    2019-10-15T10:28:53.840+0800: 99.335: [GC (Allocation Failure) [PSYoungGen: 37777K->37733K(72192K)] 192997K->192953K(268288K), 0.0377579 secs] [Times: user=0.01 sys=0.01, real=0.04 secs] 
    2019-10-15T10:29:06.706+0800: 112.201: [GC (Allocation Failure) [PSYoungGen: 63333K->53736K(78848K)] 218553K->218157K(274944K), 0.0216211 secs] [Times: user=0.08 sys=0.05, real=0.02 secs] 
    2019-10-15T10:29:06.727+0800: 112.223: [Full GC (Ergonomics) [PSYoungGen: 53736K->22503K(78848K)] [ParOldGen: 164421K->195543K(261120K)] 218157K->218047K(339968K), [Metaspace: 3964K->3964K(1056768K)], 0.0354184 secs] [Times: user=0.05 sys=0.02, real=0.04 secs] 
    2019-10-15T10:29:19.435+0800: 124.930: [GC (Allocation Failure) [PSYoungGen: 47505K->47535K(86016K)] 243049K->243079K(347136K), 0.0192741 secs] [Times: user=0.05 sys=0.00, real=0.02 secs] 
    2019-10-15T10:29:29.547+0800: 135.041: [GC (Allocation Failure) [PSYoungGen: 67433K->50535K(91136K)] 262976K->262882K(352256K), 0.0232305 secs] [Times: user=0.05 sys=0.03, real=0.02 secs] 
    2019-10-15T10:29:39.623+0800: 145.118: [GC (Allocation Failure) [PSYoungGen: 70435K->39750K(93696K)] 282781K->282733K(354816K), 0.0192353 secs] [Times: user=0.05 sys=0.00, real=0.02 secs] 
    2019-10-15T10:29:39.642+0800: 145.137: [Full GC (Ergonomics) [PSYoungGen: 39750K->21803K(93696K)] [ParOldGen: 242983K->260769K(325632K)] 282733K->282572K(419328K), [Metaspace: 3964K->3964K(1056768K)], 0.0280720 secs] [Times: user=0.06 sys=0.00, real=0.03 secs] 
    2019-10-15T10:29:49.799+0800: 155.294: [GC (Allocation Failure) [PSYoungGen: 41703K->19867K(39936K)] 302472K->302440K(365568K), 0.0166059 secs] [Times: user=0.03 sys=0.02, real=0.02 secs] 
    2019-10-15T10:30:00.007+0800: 165.502: [GC (Allocation Failure) [PSYoungGen: 39765K->19867K(87040K)] 322337K->322267K(412672K), 0.0201685 secs] [Times: user=0.00 sys=0.03, real=0.02 secs] 
    2019-10-15T10:30:00.027+0800: 165.522: [Full GC (Ergonomics) [PSYoungGen: 19867K->0K(87040K)] [ParOldGen: 302400K->322185K(385024K)] 322267K->322185K(472064K), [Metaspace: 3964K->3964K(1056768K)], 0.0175613 secs] [Times: user=0.03 sys=0.03, real=0.02 secs] 
    Heap
     PSYoungGen      total 87040K, used 6995K [0x00000000d5f80000, 0x00000000dfb00000, 0x0000000100000000)
      eden space 19968K, 35% used [0x00000000d5f80000,0x00000000d6654c80,0x00000000d7300000)
      from space 67072K, 0% used [0x00000000db980000,0x00000000db980000,0x00000000dfb00000)
      to   space 69632K, 0% used [0x00000000d7300000,0x00000000d7300000,0x00000000db700000)
     ParOldGen       total 385024K, used 322185K [0x0000000081e00000, 0x0000000099600000, 0x00000000d5f80000)
      object space 385024K, 83% used [0x0000000081e00000,0x00000000958a2570,0x0000000099600000)
     Metaspace       used 3970K, capacity 4628K, committed 4864K, reserved 1056768K
      class space    used 435K, capacity 464K, committed 512K, reserved 1048576K
    

    底层没有做GC的时候,任何日志是没有的,只有当底层做了GC才会有这个日志,通过这个日志就可以知道我们的应用程序执行GC的频率以及为什么会去做GC?

    可以看到我们的heaptest测试的时候频繁发生FullGC,因为list添加的对象都是有用的对象,old区满就会出现Full GC
    一般不用管minor GC,因为速度很快,主要侧重点在于Full GC

    相关文章

      网友评论

          本文标题:Java虚拟机学习(二)

          本文链接:https://www.haomeiwen.com/subject/fxujmctx.html