欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-24 10:22:16
...

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

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线程在等待这把锁,导致锁的嵌套了

注意:

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

如何定位死锁

开发环境:

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

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

生产环境:

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

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

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

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

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

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

调优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 指定快照存储的路径

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

内存泄漏怎么定位

其实和内存溢出一样定位

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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