目录
四、内存泄露
4.1 内存的分配和回收
4.1.1 内存段导致内存泄露
4.2 内存泄露的检测、定位及处理 —— vmstat/bcc
4.2.1 案例分析
4.2.2 检查内存泄露的工具 —— memleak
4.3 Java 项目内存泄露的监控
4.3.1 出现内存泄露的可能现象
4.4 总结
什么是内存泄露?
- 没正确回收动态分配后的内存,导致内存泄漏
- 访问的是已分配内存边界外的地址,导致程序异常退出
什么是内存溢出(OOM)?
- 程序在申请内存时,没有足够的内存空间供其使用
用户空间内存包括不同的内存段(只读段、数据段、堆、栈以及文件映射段),这些内存段是应用程序使用内存的基本方式。
哪些内存段会导致内存泄漏?
内存泄露危害
内存泄露危害很大,这些忘记释放的内存,不仅应用程序自己不能访问,系统也不能把他们再次分配给其他应用。内存泄露不断累积,甚至会消耗尽系统内存。虽然系统可以通过 OOM 机制杀死进程,但进程在 OOM 之前,可能已经引发了一连串的反应,导致严重的性能问题。
- vmstat —— 观察内存的变化情况
- bcc —— Linux 性能分析工具,用来动态追踪进程和内核行为
安装后的工具路径:
/usr/share/bcc/tools # install sysstat docker sudo apt-get install -y sysstat docker.io # Install bcc sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD echo "deb https://repo.iovisor.org/apt/bionic bionic main" | sudo tee /etc/apt/sources.list.d/iovisor.list sudo apt-get update sudo apt-get install -y bcc-tools libbcc-examples linux-headers-$(uname -r)
memleak 可以跟踪系统或指定进程的内存分配、释放请求,然后定期输出一个未释放内存和相应调用栈的汇总情况(默认5秒)
# -a 表示显示每个内存分配请求的大小以及地址 # -p 指定案例应用的 PID 号 $ /usr/share/bcc/tools/memleak -a -p $(pidof app)
#查看java进程的堆的配置信息,各区的空间大小和配置信息 jmap -heap pid jmap -histo pid | head -20 #监控jvm的GC(垃圾回收情况) jstat -gcutil pid 1000 100 //后面两个数字表示1000毫秒时间刷新一次 一共刷新100次
#图形界面 Jconsole Jvisualvm
#java_dump文件 jmap -dump:live,format=b,file=xxx pid
#java_dump文件 jmap -dump:live,format=b,file=xxx pid #java堆栈日志 jstack -l <pid> >> dump.log