欢迎关注赵强老师微信公众号:myitshare

一、什么是内存溢出?

内存溢出(OOM:out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。

在Java中,将会产生java.lang.OutOfMemoryError。看下关于的官方说明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. 意思就是说,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:非exception,因为这个问题已经严重到不足以被应用处理)。

二、为什么产生OOM?

为什么会没有内存了呢?原因不外乎有两点:

  • 分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少。
  • 应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。

在Java语言中,由于存在了垃圾自动回收机制,所以,我们一般不用去主动释放不用的对象所占的内存,也就是理论上来说,是不会存在“内存泄露”的。但是,如果编码不当,比如,将某个对象的引用放到了全局的Map中,虽然方法结束了,但是由于垃圾回收器会根据对象的引用情况来回收内存,导致该对象不能被及时的回收。如果该种情况出现次数多了,就会导致内存溢出,比如系统中经常使用的缓存机制。Java中的内存泄露,不同于C++中的忘了delete,往往是逻辑上的原因泄露。

三、如何分析Java OOM?

在故障定位(尤其是out of memory)和性能分析的时候,经常会用到一些文件来帮助我们排除代码问题。这些文件记录了JVM运行期间的内存占用、线程执行等情况,这就是我们常说的dump文件。常用的有heap dump和thread dump(也叫javacore,或java dump)。我们可以这么理解:heap dump记录内存信息的,thread dump是记录CPU信息的。这里我们重点介绍heap dump。
heap dump文件是一个二进制文件,它保存了某一时刻JVM堆中对象使用情况。HeapDump文件是指定时刻的Java堆栈的快照,是一种镜像文件。Heap Analyzer工具通过分析HeapDump文件,哪些对象占用了太多的堆栈空间,来发现导致内存泄露或者可能引起内存泄露的对象。

四、案例

首先,我们来开发一段Java程序。

import java.util.*;public class Test {public static void main(String[] args) {List<String> list = new ArrayList<String>();int i = 0;while (true) {list.add(new String("test"));  }}}

使用下面的命令运行该程序时设置JVM的堆内存(heap size)的极限值为10M(-Xmx10m)。

java -Xmx10m Test

很快,程序将会产生OOM的错误,如下图所示:

五、如何生成Head Dump文件?

我们可以在运行Java程序的时候,加入下面的参数:

-XX:+HeapDumpOnOutOfMemoryError

此参数是帮助生成dump文件,程序启动后直到抛出OOM异常。异常抛出后,在程序的classpath下会生成以一个以.hprof结尾的文件,如:java_pid4504.hprof,这就是我们需要的dump文件。

如下图所示:

六、使用IBM heapAnalyzer分析Head Dump文件

IBM heapAnalyzer(https://www.ibm.com/support/pages/ibm-heapanalyzer)是IBM开发的强大的内存dump分析工具,,IBM heapAnalyzer是通过分析OOM后的Java heap dump文件的,通过对dump文件的分析找到内存可能泄露的点。

启动IBM heapAnalyzer,并导入刚才生成的Heap Dump文件,如下图所示。

通过分析我们会发现,系统94.19%的内存都被一个ArrayList占用了(里面保存的都是Object)。这里就有可能是一个内存的溢出点。当然,我们这个例子非常典型,在实际工作可能没有这么明显,需要具体问题具体分析。

hprof文件分析工具_【赵强老师】如何分析Java的内存溢出问题相关推荐

  1. javacore分析工具_线上死锁定位分析

    " 记录一次线上死锁的定位分析."        昨晚睡觉前提了点代码到 jfoa(https://github.com/JavaFamilyClub/jfoa) 怎么也没想到导致 ...

  2. 数据字典在sga的哪一个组件中缓存_【赵强老师】Oracle数据库的内存结构

    首先,我们通过一张图片来了解一下Oracle数据库的内存结构,如下: 每个数据库实例有两个关联的内存结构-系统全局区(SGA),程序全局区(PGA). 系统全局(SGA):一组共享的内存结构(称为SG ...

  3. oracle uv,【赵强老师】Oracle数据库的内存结构

    首先,我们通过一张图片来了解一下Oracle数据库的内存结构,如下: 每个数据库实例有两个关联的内存结构-系统全局区(SGA),程序全局区(PGA). 系统全局(SGA):一组共享的内存结构(称为SG ...

  4. javacore分析工具_「赵强老师」如何分析Java的内存溢出问题

    一.什么是内存溢出? 内存溢出(OOM:out of memory)通俗理解就是内存不够,通常在运行大型软件或游戏时,软件或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出. 在J ...

  5. oracle select 行数据_【赵强老师】什么是Oracle的数据字典?

    欢迎关注赵强老师微信公众号:myitshare 数据字典是oracle存放有关数据库信息的地方,几乎所有的系统信息和对象信息都可在数据字典中进行查询.数据字典是oracle数据库系统的信息核心,它是一 ...

  6. oracle 锁表如何查看_【赵强老师】第一个Oracle的手工备份和恢复

    欢迎关注赵强老师微信公众号:myitshare 一.什么是手工管理的备份与恢复? 尽管在Oracle中,已经有了RMAN的备份与恢复.但是作为Oracle备份恢复的一种方式,我们将在本文中通过一个例子 ...

  7. redis 发布订阅实际案例_【赵强老师】Redis的消息发布与订阅

    欢迎关注赵强老师微信公众号:myitshare Redis 作为一个publish/subscribe server,起到了消息路由的功能.订阅者可以通过subscribe和psubscribe命令向 ...

  8. 【赵强老师】大数据平台的整体架构

    先看视频. [赵强老师]大数据平台的整体架构 大数据平台中的主要组件,如下: HDFS(Hadoop分布式文件系统) 源自于Google的GFS论文,发表于2003年10月,HDFS是GFS的山寨版. ...

  9. 【赵强老师】Oracle RMAN脚本基础

    还是跟以往的风格一样,我们通过一个小视频先了解一下,如何使用RMAN进行数据库的备份和恢复. [赵强老师]Oracle RMAN脚本基础 RMAN在数据库服务器的帮助下实现数据库文件.控制文件.数据库 ...

最新文章

  1. 在Vmware中安装Ubuntu
  2. 46. AngularJS所有版本下载
  3. 使用vim保存权限不够的文件
  4. xshell自动化脚本
  5. btc比特币 钱包简介
  6. 第一章 初识Mysql
  7. 五、Netty核心组件
  8. 《深入理解NGINX 模块开发与架构解析》之摘抄学习
  9. ssm框架图片上传与显示_SSM在线考试系统
  10. 现在做网络推广,哪种方式最好?
  11. 运输层详解(二)(TCP)
  12. Spring Boot 2.x 集成 Quartz 定时器 jdbc 持久化、配置集群
  13. Web API 文档生成工具 apidoc
  14. FreeTextBox的使用
  15. java打印sscil码_SSCI期刊投稿指南库
  16. cookie基础知识
  17. 8款国内外主流商业智能BI工具分析,助你轻松选型!
  18. 手把手教你---猿如意之八大高效利器使用
  19. 使用myEclipse开发Hibernate项目的步骤
  20. PFX文件解析及读取、写入、删除相关操作

热门文章

  1. 采用Memcached实现分布式Session
  2. Linux线程(四)
  3. 拥抱智能,AI视频编码技术的新探索
  4. Hulu直播服务难点解析(三):关键收获
  5. 百度Java电面一面面经
  6. 腾讯云前端性能优化大赛火热招募中!
  7. 由STGW下载慢问题引发的网络传输学习之旅
  8. 威胁情报大会直击 | 企业IT部王森:腾讯企业终端安全管理最佳实践
  9. 对象存储S3访问姿势
  10. linux命令行输入下一行但不运行命令