美文网首页
JVM调优,程序员必须掌握的知识

JVM调优,程序员必须掌握的知识

作者: Sunny捏 | 来源:发表于2020-06-19 15:25 被阅读0次

    调优之前,得知道什么样的对象会进入老年代

    1.大对象(当survivor区产生了大对象,则会进入老年代)
    2.长期存活对象(对象一直在被引用着,年龄大于15,则会进入老年代)
    3.空间担保对象(当瞬间新生代的空间满了,但是对象都被引用着,这个时候就会对象转到老年代中去)
    4.动态年龄对象(当survivor区,对应的对象年龄如果50%大于survivor区的平均年龄则进入老年代)

    什么时候会发生full gc

    当我们的堆空间都放不下对象了,则会发生full GC,不过full GC会很慢,但是也是根据堆空间的大小来算回收时间的

    调优1.如何定位死锁代码

    产生死锁的原因

    当一个线程在获取这把锁,另外一个线程在等待这把锁,这样就导致了锁的嵌套,如图
    Thread-12线程获取了 "0x00000006c1c043f0" 这把锁,而nio-8080-exec-1用户线程等待这把锁,nio-8080-exec-1获取了"0x00000006c1c4f0d0"这把锁,而Thread-12线程在等待这把锁,导致锁的嵌套了

    注意:

    死锁后程序还能够正常运行,因为死锁只是单个线程死锁了而已,
    但是你重复执行死锁的那个方法就会导致整个线程池不可用,那么其他方法就没有线程去执行了
    

    如何定位死锁

    开发环境:

    在开发的过程中,可以通过oracle的jdk,bin目录下的jvisualvm.exe查看是否死应用锁,且会发现有线程一直在休眠状态

    生产环境:

    1.可以通过jps命令查看当前运行的java程序的pid

    2.通过jstack 228 > test.txt(当前程序的pid)命令,将内容打印到test文本,来查看程序是否死锁,以及程序的详细信息
    3.打开打印出来的文本,搜索 "deadlock" 来判断是否产生死锁,如果搜索到就证明产生了死锁,下图这样,就代表产生了死锁

    4.通过用户线程,在文本中搜索用户线程的名称,就可以大概定位到死锁的代码位置

    调优2.内存溢出怎么定位

    首先内存溢出(oom)分为两种情况

    1.内存溢出
    2.内存泄漏

    内存溢出怎么定位

    有大对象的出现
    看大对象被谁引用 通过线程快照 定位到哪一行出现

    我这里学习的时候是配置了JVM参数,在IDEA里面设置的

    windows: -Xloggc:D:\logs\gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\heapdump.dump
    linx:java -jar -Xloggc:/usr/local/software/test/logs/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/software/test/heapdump.dump jvm.jar
    

    各个参数的意思是:
    -Xloggc:打印日志到某个盘符下
    -XX:+HeapDumpOnOutOfMemoryError 内存溢出时,打印堆内存快照
    -XX:HeapDumpPath 指定快照存储的路径

    当内存发生溢出的时候,java会通过参数自动打印快照到我们指定的路径,并且打印的快照都挺大的~

    接着通过oracle的jdk自带的jvisualvm.exe工具来打开这个快照

    打开之后就如下图这样,注意记录一下异常线程,然后打开显示线程

    然后将下面的内容Copy到一个新文本文件中,方便我们定位错误

    接着搜索刚刚记录的异常名称,就可以大概定位到哪一行代码发生了内存溢出了

    如何查看大对象是谁,首先点到类按钮,然后点击大小,就可以看到这个对象占了整个堆的99.5%的内存

    接着双击byte[]对象,就可以发现byte[]对象是被ArrayList的所引用的

    内存泄漏怎么定位

    其实和内存溢出一样定位

    内存泄漏和内存溢出的区别

    内存泄漏,对象不可被GC回收
    内存溢出,对象会被GC进行回收

    可以通过jstat -gcutil pid命令来查看对应java的进行GC情况,并且也可以通过此命令来查看异常是内存溢出还是内存泄漏了

    看下图可以知道,内存溢出,Eden区和Old区是被回收掉了,但是内存泄漏Eden区和Old区是没有被回收

    s0: 新生代survivor space0简称 就是准备复制的那块 单位为%
    s1:指新生代s1已使用百分比,为0的话说明没有存活对象到这边
    e:新生代eden(伊甸园)区域(%)
    o:老年代(%)
    ygc:新生代回收次数
    ygct:minor gc耗时
    fgct:full gc耗时(秒)
    GCT: ygct+fgct 耗时

    调优3.服务器CPU100%问题怎么去定位

    1.首先通过 "top"命令,来查看哪些应用占用CPU内存过高

    2.通过ps -mp pid -o THREAD,tid,time命令,可以查看当前系统哪些程序占用CPU率比较高

    注意:下图的TID是10进制的
    ps -mp 2785 -o THREAD,tid,time

    3.通过jstack pid 命令查看程序,用户线程的NID以及它的状态

    jstack 2785 > a.txt    注意:2785是程序pid 不是线程id,且是将详细内容打印到a文本当中哦~
    

    因为上图中的TID是10进制,所以我们要把他转换成16进制在进行查找
    我们将上图中的TID为2802转成16进制为af2,所以我们直接在打印出来的文本去查找,af2即可找到那个方法占用率高

    调优4.根据业务需求来进行调优

    看如下博客:https://www.itcodemonkey.com/article/1755.html?utm_medium=hao.caibaojian.com&utm_source=hao.caibaojian.com

    相关文章

      网友评论

          本文标题:JVM调优,程序员必须掌握的知识

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