最近写了个 python 通过 Jpypt 调用 kotlin 编译出的 jar,遇到了 jvm OOM (内存溢出)问题,记录分享一下排查解决过程
使用 gc log 查看内存和堆使用情况
jvm配置
jvm 配置以下:
-Xlog:gc*:file=gc.log:tags,uptime,time,level
运行后会在当前目录生成gc.log文件
log查看技巧
一行典型的 GC 日志可能长这样,主要关注第四行堆内存大小变化:
[0.348s][info][gc,start ] GC(0) Pause Young (Normal) (G1 Evacuation Pause)
[0.348s][info][gc,heap ] GC(0) Eden regions: 10->0 Survivors: 1->1 Old: 0->0
[0.349s][info][gc,metaspace ] GC(0) Metaspace: 10504K->10504K(10752K)
[0.349s][info][gc ] GC(0) Pause Young (Normal) 5M->1M(20M) 1.234ms
[0.348s]:这是 uptime,表示从 JVM 启动到此 0.348 秒时发生的事件。[info]:日志级别。你也可以在参数里打开debug或trace,得到更详细的内部信息。[gc,start]:子系统标签,这里是 GC 开始时的消息。GC(0):第 0 次 GC。后续 GC 会依次编号。Pause Young (Normal) (G1 Evacuation Pause):触发原因和 GC 类型。5M->1M(20M):GC 之前堆中可用的大小变化:回收前 5 MB,回收后 1 MB,堆最大 20 MB。1.234ms:这次 GC 的暂停时长。
使用 Jconsole 和 Jcmd 排查OOM 问题
jvm配置
jconsole
启动 jvm 需要配置以下:
"-Dcom.sun.management.jmxremote",
"-Dcom.sun.management.jmxremote.port=9010",
"-Dcom.sun.management.jmxremote.local.only=false",
"-Dcom.sun.management.jmxremote.authenticate=false",
"-Dcom.sun.management.jmxremote.ssl=true",
"-Djdk.attach.allowAttachSelf=true",
连接进程
选择 local 进程,名字没有配置就是空字符串的那个,提示 ssl 弹窗选择 “不安全的连接”
查看堆内存用量变化曲线

查看各个类的实例数量及大小
- 方式一:

参数输入空字符串即可,但这里我实测好像不能输入参数,所以使用下面的方式二
- 方式二
jcmd [your_pid] GC.class_histogram

ok, 解决吧
2457

被折叠的 条评论
为什么被折叠?



