一个对象不再使用后,(因其从GC Root仍有引用链可达)却未被JVM回收,白白占着内存,即内存泄漏,这个效果累积,最后就会OOM。
发现:设置监控告警,内存占用超过阈值就发送警告邮件
诊断:借助分析工具
修复:修复代码或做设计方案调整
验证
Linux下:
top
相关项:
top只适合做一个初步的筛查,判断问题在哪个进程。
可视化分析工具,Oracle JDK 6~8 中自带,双击运行:
Oracle JDK 9之后需要单独安装,下载地址:https://visualvm.github.io/
本地启动Visual VM:
解压即可使用,双击启动:
这里展示了当前本地启动的Java进程:
切换到Monitor监控tab页,这里有CPU、堆、元空间、类、线程,可勾选要展示和监控的内容:
看下整体信息,正常展示了我在IDEA加的启动JVM参数:
查看堆和元空间的走向:这里有size向max扩容的知识点,别看到高的线就认为空间不足
IDEA的插件版的Visual VM:
安装完成后,再次setting-> Other Setting,选择exe的目录:
此时的这两个按钮,就等于普通的debug / run 再加一个启动Visual VM:
点击启动程序,直接打开Visual VM,并定位到这个进程。
Visual VM远程监控线上服务:
以上为本地的监控,如果是远程线上服务的监控,需要添加JVM参数:
java -jar
-Djava.rmi.server.hostname=10.4.134.198 //hostname为远程主机地址
-Dcom.sun.management.jmxremote //开启jmx远程访问的功能
-Dcom.sun.management.jmxremote.port=80 //设置jmx远程访问的端口号,比如9122
-Dcom.sun.management.jmxremote.rmi.port=80
-Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false //关掉ssl以及认证这两个安全与权限的认证
demo-0.0.1.jar
打开jmx,选远程,右键Add Remote Host:
右键Add JMX Connection:
加上前面的端口:
监控成功:
但不建议给生产环境用,因为要保证生产环境的稳定,而Full GC和Heap Dump生成内存快照的这两个功能会停止用户线程。还有,如果是集群化部署,不是上面的java -jar一个jar包,远程就很不方便。
//连接远程踩坑帖子
https://blog.csdn.net/qq_27641935/article/details/102919542
微服务架构下,在每个pod里去启动Arthas很繁琐(当然临时排查一下某单个服务的话这样也挺好),可以使用Arthas的tunnel管理所有的需要监控的服务。实现步骤:
//tunnel服务端jar是是一个Spring Boot插件打的jar,可直接启动
//-Darthas.enable-detail-pages=true参数,让tunnel提供一个页面供我们去看注册上来的应用,默认8080端口访问
nohup java -jar -Darthas.enable-detail-pages=true arthas-tunnel-server-3.7.1-fatjar.jar &
Arthas的tunnel(隧道),适用于生产、测试环境下,管理微服务的集群。
//见鬼,为什么-Dserver.port=8081会端口占用,--server.port=8081就没事
-Dserver.port=8081
--server.port=8081
Promethus收集应用的数据,Grafann以可视化方式展示。首先需要微服务中引入actuator,以http的方式将服务对应的指标向外暴露,以便Promethus收集
配置:
再引入另一依赖:micrometer,将JVM、数据库连接池的信息、磁盘信息等收集上来,组装成Prometheus能识别的格式
调接口看下暴露出来的promethues相关的端点信息
再往后就是Promethues的部署、连接了。略了。
正常的堆内存变化图:
特点:
有内存泄漏的堆内存变化图:
特点:
最后,可以使用Visual VM的采样tab页,查看当前堆里的对象信息。点Perform GC来Full GC,发现这块空间一直不能降,大概率问题就在这儿。