网站首页 > 博客文章 正文
在这篇文章中,我们将介绍基于JVM的应用程序的内存问题症状,我们可以使用哪些工具来诊断它们以及如何修复它们。
症状
以下是一些内存问题的症状:
应用程序性能差
内存使用异常
OutOfMemory错误(OOME)
糟糕的应用性能
应用程序未达到预期水平
响应时间长
删除客户端请求
卡住的线程
服务不可用
应用程序日志中的时间戳差距较大
内存问题的原因:
配置错误的内存
旧一代内存空间的尺寸小于实时对象集。这会触发主要的垃圾收集(GC),导致更大的暂停。
代码缓存小于生成的编译代码封装
年轻一代的体型不合适导致过早提升对象
PermGen / Metaspace的大小不正确,导致完整的GC
内存泄漏 - 无意中保留内存空间中的对象
无意引用堆中的对象集
不要取消引用类似于classky的类加载器实例
不适当地释放本地资源
终结者过度使用
终结者的对象可能会延迟他们自己的GC
Finalizer线程在回收它们之前需要调用实例的finalize()方法
只能有1个Finalizer线程。如果它跟不上对象可用于最终化的速度,那么JVM会因OOME而失败
挂起终结器对象基本上是累积垃圾
Java 9中已弃用终结器
显式GC调用
System.gc() 并且诊断数据收集可能会导致长时间停顿
-XX:+DisableExplicitGC 可以禁用System.gc()调用
-XX:+PrintClassHistogram接收kill -3
信号时也会调用显式GC
OutOfMemoryError
层次结构:Throwable->Error->VirtualMachineError->OutOfMemoryError
(未经检查的异常)
JVM在各种内存空间中运行空间不足或无法继续执行进程时抛出。一些可能性:
本地空间用于Java线程堆栈,加载的jar,zip,本地库,本地资源(如文件); 从本地代码分配的mem
无法分配更多本机内存或创建新线程或本机内存泄漏
在64位计算机上运行32位JVM会限制进程大小4 GB
Java堆的位置可以限制本地堆的最大大小。可以通过选项-XX控制:HeapBaseMinAddress = n指定地址本机堆应该基于
完整的GC被调用,但无法释放Metaspace中的空间,应用程序正试图加载更多的类
Metaspace默认为“无限”,但可以由MaxMetaspaceSize控制。默认情况下,为压缩类空间保留1 GB
确保-Xnoclassgc未被使用,因为它阻止卸载类
声称空间非常少的GC太多
应用程序线程没有获得任何CPU周期
JVM已经调用完整的GC,但无法释放空间
堆的尺寸可能小于应用程序的尺寸,或者应用程序不必要地持有堆中的某些对象
堆空间已满
GC超出限制
请求的阵列大小超过VM限制
PermGen空间/ Metaspace /压缩类空间
本机内存 - 使用本地方法进行交换空间/堆栈跟踪
CodeCache警告
由JVM打印的警告消息说CodeCache已满,编译器已被禁用。
代码缓存已满时无OOME
Sweeper进行紧急清理。这可能会丢弃已编译的代码,JIT可能需要再次执行优化
使用ReservedCodeCacheSize选项确保合适的CC大小
直接缓冲存储器
ByteBuffer.allocateDirect(N) :使用幻影引用和引用队列进行垃圾回收的直接缓冲区
默认情况下内存不受限制,但可以通过-XX:MaxDirectMemorySize = n进行控制
由Java NIO使用。用于I / O的堆ByteBuffer使用临时直接ByteBuffer
诊断数据,数据收集和分析工具
内存泄漏故障排除
确认内存泄漏
随时监控堆的使用情况
如果完整的GC无法在OldGen中声明空间,可能是配置问题
堆大小可能太小 - >增加堆大小和监视器!如果问题依然存在,则可能是内存泄漏
-XX:+GCTimeLimit
设置GC可花费的时间总量的时间上限,默认为98%-XX:+GCHeapFreeLimit
GC应释放的空间量设置下限,表示为最大堆的百分比,默认值为2%OutOfMemoryError
如果之前的5个连续GC不能保持GC成本低于GCTimeLimit
或至少GCHeapFreeLimit
空间释放,则在全GC之后抛出PermGen/Metaspace
Metaspace
如果频繁的Full GC不要求任何空间,可能会太小
诊断数据和分析
本机内存跟踪器输出 - 跟踪JVM内部使用的本机内存,而不是外部库。用NativeMemoryTracking选项启动JVM
pmap,libumem,valgrind,核心文件
使用JConsole,jmap收集数据
使用堆转储使用Eclipse MAT / Visual VM进行分析
启用堆统计。可以引入额外的性能开销
要创建一个航班记录:
-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=delay=20s,duration=60s,name=Rec,filename=lol.jfr,settings=profile
飞行记录可以找出泄漏物体的类型,但是您需要堆转储才能找出造成物体泄漏的原因
收集使用:
-XX:+PrintClassHistogram
并SIGQUIT
在Posix和SIGBREAK
Windows上jcmd pid GC.class_histogram filename=histo
jmap -histo pid core_file
jhsdb jmap
(Java 9)
我们可以通过以下方式进行堆转储:
Eclipse内存分析工具(MAT)显示泄露嫌疑人,直方图,不可达对象,重复类,GC根的引用链,允许使用OQL来探索堆转储。
JMC和Java VisualVM的JOverFlow,YourKit(商业分析器)都可以进行堆转储。
jcmd pid GC.heap_dump heapdump.dmp
jmap -dump:format = b,file = snapshot.jmap pid
使用MBean HotSpotDiagnostic的JConsole或Java Mission Control
OOM错误上的JVM选项堆转储:-XX:+ HeapDumpOnOutOfMemoryError。频繁的完整GC可能会延迟收集堆转储和重新启动进程
对于Java 9+,G1选项是:
-Xlog:gc*,gc+phases=debug:file=gc.log . For non G1, -Xlog:gc*:file=gc.log
。对于较旧的JVM,-XX:+PrintGCDetails, -XX:+PrintGCTimeStamps, -XX:+PrintGCDateStamps, -Xloggc:gc.log
为了检查metaspace,
-verbose:class
或者-XX:+TraceClassLoading , -XX:+TraceClassUnloading
我们可以通过人工检查,GCViewer,GCHisto,gceasy.io分析日志
GC日志有助于确定堆需求,找出过多的GC和较长的GC暂停以及配置内存空间
堆转储有助于确定意外的内存增长和内存泄漏。
堆直方图 - 快速查看堆中的对象
Java飞行记录 - 意外的内存增长和内存泄漏,GC事件
终结
本机内存
结论
在这个系列中,我们看看了JVM如何管理内存以及垃圾收集过程如何工作。我们还了解了如何诊断内存问题,哪些工具可用于收集和分析诊断信息以及可能影响应用程序性能的一些JVM选项。
- 上一篇: 互联网大厂面试系列-面试被问到什么是JVM的逃逸分析?
- 下一篇: 面试官问我JVM问题,我直接回怼他
猜你喜欢
- 2024-09-18 3分钟搞清楚 JVM逃逸分析(java 逃逸对象)
- 2024-09-18 天天都是面对对象编程,你真的了解你的对象吗?
- 2024-09-18 做JAVA开发的同学一定遇到过的爆表问题,看这里解决
- 2024-09-18 线上一次fullgc搞得鸡飞狗跳后,我总结了这篇文章
- 2024-09-18 Java中的对象都是在堆上分配的吗?
- 2024-09-18 jvm 相关的线上问题,内存使用率飙升到 90%+ 等 处理手段
- 2024-09-18 面试官问我JVM问题,我直接回怼他
- 2024-09-18 互联网大厂面试系列-面试被问到什么是JVM的逃逸分析?
- 2024-09-18 内存溢出OutOfMemoryError科普系列一
- 2024-09-18 读Java性能权威指南(第2版)笔记11_堆内存上
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)