JVM–实战篇

内存调优

内存泄漏详述

什么是内存泄漏

一个对象不再使用、但是它依然在GCRoot引用链上、不会回收–>内存泄漏

据大多数情况是堆内存泄露引起的

最终会导致内存溢出,但是内存溢出不一定只是内存泄漏导致的

内存泄漏的场景

  • 用户多了,调用了登录接口但是没有调用到退出登录接口
  • 任务调度 例如spring的任务调度

发现与解决

发现–>诊断–>修复–>验证

-top命令

关注RES常驻内存

*优点:操作简单不用额外安装数据

*缺点:只能看最基础的进程信息,无法查看每个部分的内存占用(堆、方法区、堆外

-Visual VM

*优点:支持IDEA插件、功能丰富实时监控

*缺点:大量集群化 需要手动

-Arthas

*优点:功能强大、粒度小、支持集群

*使用:加依赖、arthas配置、打包部署运行、启动应用程序

-Prometheus+Grafana

*优点:警告,邮件,短信通知等

*缺点:环境搭建复杂

哪些方式会产生内存泄漏:

一、代码问题

  • equals和hashcode

没有重写hashcode和equals导致相同的id的学生随机出来的值不同。equals比对的是地址。避免用对象整体作为KEY。

  • 内部类引用外部类

外部类不再使用,内部内不算内存泄漏对象,而外部类算

怎么改:静态。那么在创建内部类的时候就和外部没有关系

  • 匿名内部类对象 在 非静态方法中被创建 会持有调用者对象 不能被回收
  • ThreadLoacal

线程池,记得使用remove

  • String的Intern方法

JDK6中 字符串常量在堆内存的Perm Gen永久代中 一直调用intern放进常量池中

若产生了引用关系(放入List)不会回收就溢出

=256M

若在其它版本JDK8 也会出现outofmemory

  • 通过静态字段保存对象
  • 资源没有正常关闭

资源没有close,不是必然的会内存泄漏

二、并发请求问题

内存对象积压:同时并发请求大200,内存加载数据多,请求处理时间长

**定位是哪一个接口产生的**

工具:Jmeter

诊断–内存快照

监控JAVA内存的常用工具

常见场景

解决方案

GC调优

日志、系统假死详述

性能调优

jhm


评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Translate »