深陷好几天了。。堆内存占用不高, Java 进程内存占用非常高,不明白是什么情况...

2020-01-07 11:54:09 +08:00
 bubuXiaoqi

找不到谁可以问问。。。 深陷几天了。。

1、top 查看显示占用 3.G 了 但是我用 jmap -head 拿下来的文件也就 1.2G 2、jstack -gc 查看的各代内存都很正常都是用了几百 M 完全没有满 加起来也就 1G 的样子 3、 不知道该怎么定位了,CPU 非常正常。。把机器内存快跑满的时候 CPU 和负载都很正常

4507 次点击
所在节点    Java
20 条回复
bubuXiaoqi
2020-01-07 11:55:37 +08:00
而且我用 JProfiler 分析也看的内容大小只有 8 900M 看类分析也没有内存泄漏的情况,如果有的话堆内存应该比较高的吧
b1gCi
2020-01-07 11:58:41 +08:00
堆外内存看看,分析下类,是否有流没有正常关闭之类的,或者打开文件太多了来不及回收,上次被这个问题坑了
bubuXiaoqi
2020-01-07 12:03:56 +08:00
@b1gCi 堆外内存通过啥工具看哇。
rigortek
2020-01-07 12:04:17 +08:00
这种情况下似乎只能采用排除法,
一步一步不加载或不调用某些可疑模块,
慢慢缩少范围,直到找到“罪魁祸首”。
bubuXiaoqi
2020-01-07 12:06:58 +08:00
@rigortek 线上业务太多了。。。 而且好奇怪的是阿里云负载的相同比例的 6 个节点 有的节点啥事没有 有的节点就是慢慢、越来越大 但是拉 dump 下来就没有多少占用。。
bubuXiaoqi
2020-01-07 12:07:21 +08:00
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
37888.0 38912.0 21180.4 0.0 588288.0 224570.3 1320960.0 703979.1 216320.0 133734.7 27648.0 16647.6 72616 902.412 598 377.328 1279.741
palmers
2020-01-07 12:10:56 +08:00
你多 jmap 几次看看呢?
jerrychaox
2020-01-07 12:55:20 +08:00
看下 /dev/shm ?
sagaxu
2020-01-07 13:18:24 +08:00
gc 释放的内存,不一定会返还给 os
pmispig
2020-01-07 13:36:01 +08:00
要么你 top 读数错误,要么堆外内存
Aresxue
2020-01-07 14:03:13 +08:00
使用 Native Memory Tracker,加上-XX:NativeMemoryTracking=detail,
蒙一下 和 netty 或者文件流没有正确释放有关。
lewis89
2020-01-07 14:11:17 +08:00
@Aresxue #11 90% 跟 netty 有关,netty 堆外出事情 又不是一次两次了,关键是很多阿里系的中间件都喜欢把它引进去,在性能跟可靠性方面,我觉得绝大部分场景都不应该选这种黑魔法式的堆外内存管理方式,排查难度太大,而且它自己又搞了一套引用计数的内存管理方式,出问题了 你只能等官方去定位,除非你自己能定位到 netty 泄漏的地方。
bubuXiaoqi
2020-01-07 14:34:36 +08:00
@palmers 这几天 jmap 很多次了堆内内存没什么变化
bubuXiaoqi
2020-01-07 14:36:38 +08:00
@jerrychaox 是空文件夹
zhanggg
2020-01-07 14:40:32 +08:00
@bubuXiaoqi jvisualvm 装个插件能看
2379920898
2020-01-07 14:48:44 +08:00
先装个监控查看一下,清空下文件
limbo0
2020-01-07 15:32:38 +08:00
确定堆外内存的话,可以看看 direct 内存,网络连接多的话占用很多
bubuXiaoqi
2020-01-07 16:03:03 +08:00
@zhanggg 好我试试 好像加了一层 docker 还不明白怎么连接上。
zhanggg
2020-01-08 11:13:47 +08:00
@bubuXiaoqi docker 把相关端口挂出来,启动脚本里加上相关配置
jerrychaox
2020-02-10 15:56:33 +08:00
因为通常的垃圾收集日志等记录,并不包含 Direct Buffer 等信息,所以 Direct Buffer 内存诊断也是个比较头疼的事情。在 JDK 8 之后的版本,使用 Native Memory Tracking ( NMT )特性来进行诊断,你可以在程序启动时加上下面参数:

-XX:NativeMemoryTracking={summary|detail}


// 打印 NMT 信息
jcmd <pid> VM.native_memory detail

// 进行 baseline,以对比分配内存变化
jcmd <pid> VM.native_memory baseline

// 进行 baseline,以对比分配内存变化
jcmd <pid> VM.native_memory detail.diff

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/635737

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX