[转帖]20191022-从Jenkins NativeOOM到Java8内存
我把老掉牙的Jenkins升级了,它跑了几天好好的;后来我有一个python脚本使用JenkinsAPI 0.3.9每隔2.5分钟发送约300余get请求,结果过了3天,它就挂了;当我开两个脚本时,40.5小时就挂了。(可以通过搜索Jenkins日志/var/log/jenkins/*
中字符Jenkins is fully uo and running.
断定启动和终止时间)
在后续持续观察中,对外表现为:top中的RSS巨大,已经是设置的Xmx的3~4倍,显然不合理。
根据临终前的hs_xx日志和NMT看到,堆内存已经使用完,频繁full GC(这里说的不对,并没有频繁full GC,是我看错了日志,before和after我视为了两个),通常都是运行一段时间以后(有一个月,也有四天)突然内存暴增;经过一段时间的学习了解,可能是脚本触发了JenkinsBug, 其中的JNI调用的native code导致Native OOM,它把系统内存吃完了,再也没有内存可用了,在java进程申请新内存时,申请内存失败而退出。
曾经被pass的怀疑:
1).持有大量log造成的缓存而占用内存
2).大量TIMEWAIT造成,不够查看只有500~600,最多也不超过1000个,不应占如此大内存(同时发现之前TCP的知识没有整理,又忘光了!)
3).Test Result Analyzer 造成内存泄漏,社区一直有人在提,虽然我们装了但是我们没有一直用,比如自动刷新会导致内存泄漏
开始学习了解RSS和Xmx的具体含义,为什么他们会不一致!(我期待他们约等,我甚至按照部门旧文档给Java8设置了MaxPerSize了呢!)
新的问题是什么是堆外内存,什么是JVM native memory,还有MetaSpaceSize
它是属于哪里?它怎么增长?是否可以GC?什么是MaxDirectMemorySize
? Xss即栈内存的使用处于哪里?NativeMemoryTracking的用法?-XX:-UserCompressedOops and -XX:HeapBaseMiniAddress=n
hs_err_pid.log中MetaSpaceSize 内存的used
,capacity
,committed
,reversed
代表什么含义?
used
capacity
committed
reversed
- 堆外内存
堆外内存(off-heap)不是一个准确的叫法,不必纠结于堆外内存和Native Memory 到底谁是谁. 我看了许多网上回答,SO上有个还说MetaData在堆上的,导致我当时非常混乱,当然后来看得多了就能辨出哪个说得不对了。 64位进程的内存基本是无限使用的,native即本地,但它不会脱离于Java进程,操作系统上看到使用了常驻内存有10G,那你JVM到底怎么花费这10G内存的?为什么有4G内存在NMT中看不到去哪里了? - NativeMemoryTracking的用法:https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html
-XX:NativeMemoryTracking=[off | summary | detail]
NMT要配合jcmd使用
jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]
输出中各区域的意义和diff怎么看,文档中有详细的解释;他可以帮助你分析内存泄漏,但是
Enabling NMT will result in a 5-10 percent JVM performance drop and
memory usage for NMT adds 2 machine words to all malloc memory as
malloc header. NMT memory usage is also tracked by NMT.
但是NMT不记录非JVM申请的内存,所以native code 内存泄漏它分析不出
Since NMT doesn’t track memory allocations by non-JVM code, you may have to use tools supported by the operating system to detect memory leaks in native code.
通过NMT的输出,它把JVM使用的内存分成了 ‘Java Heap’、Class、Thread、 Code、 GC、 Compiler、 Internal、 Symbol、 ‘Memory Tracking’、 ‘Pooled Free Chunks’、 ‘Unknown’ 。Unknown 是NMT对CMS垃圾回收器支持不好。对于这几部分的解释:https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr022.html#BABCBGFA
为啥使用-XX:+UseCompressOops后,使用32位地址可以让堆最大到32GB?232=4GB呀因为默认Java对象是8字节对齐的,(比如从1 000b表示第一个对象,10 000b表示第二个对象)所以表示地址时后三位可以省去,于是计算大小是就多出了3位,236=32GB https://stackoverflow.com/questions/13549787/can-i-use-more-heap-than-32-gb-with-compressed-oops
Metaspaces
是元数据的意思,Java8 新引入来代替 perm,默认起始有22M左右,它的大小根据下图中两个Ratio自动调整,它是受垃圾回收器管理的,但是它不在堆上;committed即提交的内存,如果主机没有开swap的话,提交的内存应该都在内存中,即真正占用了主机内存就是这么多;reversed
预订(保留)的内存,即Xmx,used,capacity没看到啊??(2022年3月 used、capacity可以通过 jmap -heappgrep java
查看)其中used是真正使用的内存,capacity 是指容量 committd是指你假笨:http://lovestblog.cn/blog/2016/10/29/metaspace/ Dzone上对Metaspace和perm的对比:https://dzone.com/articles/java-8-permgen-metaspace - Java8 X和XX参数说 明 trubleshotting https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/index.htmlNativeMemory的问题 DirectMemorySize
默认的MaxDirectMemorySize和Xmx一样大,SO:https://stackoverflow.com/questions/3773775/default-for-xxmaxdirectmemorysize/54447744#54447744
推荐阅读 https://dzone.com/articles/troubleshooting-problems-with-native-off-heap-memo
中文小碟补充 https://www.cnblogs.com/duanxz/archive/2012/08/09/2630284.htmljcmd的用法:https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html#BABEHABG
搜索过程中遇到的其他类似问题:
java在容器中,docker stat 、 top内存使用和 NMT committed 内存不等问题
是docker的一个bug, 推荐阅读 https://stackoverflow.com/questions/38597965/difference-between-resident-set-size-rss-and-java-total-committed-memory-nmt
jrockit GC和内存
https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html
OutOfMemoryError:https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks002.html
JVM outOfMemory 推荐阅读
https://www.techpaste.com/2012/07/steps-debugdiagnose-memory-memory-leaks-jvm/
JVM内存管理 推荐阅读-可以翻译
https://betsol.com/2017/06/java-memory-management-for-java-virtual-machine-jvm/
推荐阅读,从为何JVM(或者普遍的程序)不把没使用的内存还给OS到怎样强制JVM退还内存 (一个进程退还了内存影响到其它程序; CMS和G1的Major GC也会暂停JVM)
https://blog.madadipouya.com/2019/01/04/jvm-does-not-release-memory/
GC日志中Allocate Failure 啥意思
https://stackoverflow.com/questions/28342736/java-gc-allocation-failure
一般是MinorGC发生的标志NativeOOM-Dzone HeapByteBuffers ‘GLIBC Allocator’
2020102 23:47 我根据下面这篇文章, 下载了Jxray,对dump的内存进行分析,发现DirectByteBuffer并没有占用很大 Native Memory,为了验证,我设置了-Djava.nio.directByteBufferSize,发现并没有起作用;文章中称,DirectByteBuffer的使用在NMT的internal中可以看到,有待考察,同时根据我的观察DirectByteBuffer小于internal大小 。现在几乎走投无路了,我取消了NMT,下面文章中一句话很经典,即使是堆外内存,在dump的堆中也能看出些蛛丝马迹,而我现在对dump文件的解读技能为零。同时对于GLIBC Allocator
我我现在认为 它只能缓解问题发生但不能解决根本问题。 另一个问题是,AWS对R型机器做了什么优化,使得他声称R4是内存优化型主机? 同时Jxray使用时注意限制堆内存大小,它的胃口很大,默认Xmx12G,刚开始脚本都没起起来报错了我还以为是它的分析结果,file cache size:3.6G,和我丢失的内存大小差不多,联想到Jenkins的日志缓存,还激动了一小阵,想想真好笑。
https://dzone.com/articles/troubleshooting-problems-with-native-off-heap-memo
向OS进发:
查看pmap的内容
http://lysu.github.io/blog/2015/02/02/how-to-deal-with-non-heap-or-native-memory-leak/
dump整个内存: gdb的gcoregcore -a
20200112
从dump的堆中来看,有400M左右的ref.finalizer, 现在怀疑是CPU资源不足,堆内存设置过大,full GC 频率过低(看过一次日志,运行了四天,21次full GC),导致finalizer清理线程没有及时清理持有的native memory,而请求频率高导致finaliable对象产生速率快,造成堆JVM整个内存过高,那么这个内存是属于哪里的呢?怎么控制?我如何核实? 关于finalizer: https://www.cnblogs.com/benwu/articles/5812903.html? :
关于finalize: http://www.enyo.de/fw/notes/java-gc-finalizers.html
2022.03.10
查看一个正在运行的JVM的参数 jcmd pid VM.flags
触发一次GC(完全等价于代码中运行System.gc()
)jcmd pid GC.run
查看一个正在运行的JVM的堆信息与垃圾回收器 jmap -heap pid
查看JVM GC原因:jstat -gccause pid 1000
每1000ms查看一次
使用NMT:-XX:+NativeMemoryTraking=detail jcmd pid VM.native_memory
当前JDK的默认参数 java -XX:+PrintFlagsFinal -version
修改运行中JVM参数 jinfo -flag flag_key=flag_value
[转帖]20191022-从Jenkins NativeOOM到Java8内存的更多相关文章
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)(转)
Java8内存模型—永久代(PermGen)和元空间(Metaspace) 查看原文点击传送门:http://www.cnblogs.com/paddix/p/5309550.html 提示:本文做了 ...
- (转)Java8内存模型—永久代(PermGen)和元空间(Metaspace)
背景:介绍java8中永久代到元空间的转变. Java8内存模型—永久代(PermGen)和元空间(Metaspace) 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法 ...
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)
一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“栈 ...
- Java虚拟机—Java8内存模型(整理版)
1.概述 对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要手动释放内存,不容易出现内存泄露和内存溢出问题.一旦出现内存泄露和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,排查错误 ...
- 【转帖】系统软件工程师必备技能-进程内存的working set size(WSS)测量
系统软件工程师必备技能-进程内存的working set size(WSS)测量 2018年12月28日 18:43:01 Linuxer_ 阅读数:145 https://blog.csdn.net ...
- [转帖]Linux分页机制之概述--Linux内存管理(六)
Linux分页机制之概述--Linux内存管理(六) 2016年09月01日 19:46:08 JeanCheng 阅读数:5491 标签: linuxkernel内存管理分页架构更多 个人分类: ┈ ...
- 转:Java8内存模型—永久代(PermGen)和元空间(Metaspace)
一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“栈 ...
- Java8内存结构—永久代(PermGen)和元空间(Metaspace)
本文转载 作者:liuxiaopeng 博客地址:https://www.cnblogs.com/paddix/p/5309550.html 一.JVM 内存结构 根据 JVM 规范,JVM 内存共分 ...
- Java8内存模型
一.JVM内存模型 内存空间(Runtime Data Area)中可以按照是否线程共享分为两块,线程共享的是方法区(Method Area)和堆(Heap),线程独享的是Java虚拟机栈(Java ...
- [转帖]运维必读:Linux 的内存分页管理
运维必读:Linux 的内存分页管理 https://cloud.tencent.com/developer/article/1356431 内存是计算机的主存储器.内存为进程开辟出进程空间,让进程在 ...
随机推荐
- 【华为云技术分享】网络场景AI模型训练效率实践
[摘要] 问题 KPI异常检测项目需要对设备内多模块.多类型数据,并根据波形以及异常表现进行分析,这样的数据量往往较大,对内存和性能要求较高.同时,在设计优化算法时,需要快速得到训练及测试结果并根据结 ...
- 【福利活动】华为云“上云之路”征文大赛开启,FreeBuds3无线耳机等重磅好礼送不停
各位关注华为云的开发者们,达嘎猴啊~ 今天带给你们一个好消息,大家心心念念的华为云"上云之路"征文大赛已经正式开启啦. 举办本次华为云"上云之路"征文大赛的目的 ...
- 可以一学的代码优化小技巧:减少if-else冗余
摘要:if-else 语句对于程序员来说,是非常非常熟悉的一个判断语句,我们在日常开发和学习中都经常看见它. 本文分享自华为云社区<JavaScript代码之美-代码优化,减少if-else冗余 ...
- 初识Selenium自动化(为什么要去用自动化?)
什么是自动化测试 让程序代替人去验证程序功能的过程 自动化测试就是把以人为驱动的测试行为转化为机器执行的一种过程 比如说:我们设计好执行脚本,通过驱动连接浏览器去模拟人去操作浏览器一般 为什么要进行自 ...
- 成为一个合格程序员所必备的三种常见LeetCode排序算法
排序算法是一种通过特定的算法因式将一组或多组数据按照既定模式进行重新排序的方法.通过排序,我们可以得到一个新的序列,该序列遵循一定的规则并展现出一定的规律.经过排序处理后的数据可以更方便地进行筛选和计 ...
- C++ Lambda 快速上手
Lambda 听起来非常的牛逼,很容易就会联想到函数式编程或者 Lambda 演算这样的东西.但是在 C++里,没那么复杂,就把它当匿名函数用就好了 HelloWorld 对于降序排序,我们可以这样写 ...
- 一些 Codeforce Content 补题记录
Codeforces Round #651 (Div. 2) 1370A. Maximum GCD 给定一个 n,求(1~n)中任意组合对的最大的公约数. 思路:如果 \(n\) 是偶数,那么最大公约 ...
- KCD技术分享:以SBOM为基础的云原生应用安全治理
随着越来越多的企业和组织将他们的应用迁移到云上,云原生技术的应用部署和管理正在变得更加灵活和高效,但也相应地引入了一些新的安全风险.2023年4月15日,由云原生计算基金会(CNCF)发起,全球各国当 ...
- 看这个视频,4万人学会云上部署 Stable Diffusion
目前大火的 AIGC 领域中, 除了 ChatGPT,Stable Diffusion 在文生图领域大放异彩,深刻影响着绘画.视频制作等相关领域.<动手吧,开发者>本期活动邀请 B 站知识 ...
- 存储密码-ssh添加秘钥