实战Java虚拟机之一“堆溢出处理”
从今天开始,我会发5个关于java虚拟机的小系列:
- 实战Java虚拟机之一“堆溢出处理”
- 实战Java虚拟机之二“虚拟机的工作模式”
- 实战Java虚拟机之三“G1的新生代GC”
- 实战Java虚拟机之四“禁用System.gc()”
- 实战Java虚拟机之五“开启JIT编译”
下面说说【实战Java虚拟机之一“堆溢出处理”】
在Java程序的运行过程中,如果堆空间不足,则有可能抛出内存溢出错误(Out Of Memory),简称为OOM。如下文字显示了典型的堆内存溢出:
- Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
- at geym.zbase.ch3.heap.DumpOOM.main(DumpOOM.java:20)
一旦发生这类问题,系统就会被迫退出。如果发生在生产环境,可能会引起严重的业务中断。为了能够不断改善系统,避免或减少这类错误的发生,需要在发生错误时,获得尽可能多的现场信息,以帮助研发人员排查现场问题。Java虚拟机提供了参数-XX:+HeapDumpOnOutOfMemoryError,使用该参数,可以在内存溢出时导出整个堆信息。和它配合使用的还有-XX:HeapDumpPath,可以指定导出堆的存放路径。
【示例3-4】以下代码合计分配了25M内存空间。
- public class DumpOOM {
- public static void main(String[] args) {
- Vector v=new Vector();
- for(int i=0;i<25;i++)
- v.add(new byte[1*1024*1024]);
- }
- }
使用如下参数执行上述代码:
-Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/a.dump
显然20M堆空间不足以容纳25M内存,系统比如发生内存溢出,在发生错误后,控制台输出如下:
- java.lang.OutOfMemoryError: Java heap space
- Dumping heap to d:/a.dump …
- Heap dump file created [23067302 bytes in 0.160 secs]
- Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
- at geym.zbase.ch3.heap.DumpOOM.main(DumpOOM.java:19)
可以看到,虚拟机将当前的堆导出,并保存到D:/a.dump文件下。使用MAT等工具打开该文件进行分析,如图所示,可以很容易地找到这些byte数组和保存它们的Vector对象实例。有关MAT等工具的使用,可以参阅《实战Java虚拟机-jvm故障诊断与性能优化》第7章。

除了在发生OOM时可以导出堆信息外,虚拟机还允许在发生错误时执行一个脚本文件。该文件可以用于奔溃程序的自救、报警或者通知,也可以帮助开发人员获得更多的系统信息,如完整的线程转存(即Thread Dump或者Core Dump)文件。
这里给出一个在发生OOM时导出线程转存的例子。准备printstack.bat脚本如下:
D:/tools/jdk1.7_40/bin/jstack -F %1 > D:/a.txt
以上脚本将会导出给定Java虚拟机进程的线程信息,并保存在D:/a.txt文件中。
使用如下参数执行上述代码:
-Xmx20m -Xms5m “-XX:OnOutOfMemoryError=D:/tools/jdk1.7_40/bin/printstack.bat %p” -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/a.dump
在程序异常退出时,系统D盘下会生成新文件a.txt,里面保存着线程转存信息。本例中,文件路径“D:/tools/jdk1.7_40”为笔者的JDK按照目录,读者可以替换成自己的JAVA_HOME目录,进行尝试。
《实战Java虚拟机》一书Q交流群:397196583
实战Java虚拟机之一“堆溢出处理”的更多相关文章
- Java虚拟机六 堆溢出的处理
在Java程序中,如果堆空间不足,有可能抛出内存溢出错误:Out Of Memory,简称OOM. Exception in thread "main" java.lang.Out ...
- 【Java】实战Java虚拟机之五“开启JIT编译”
今天开始实战Java虚拟机之五“开启JIT编译” 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实战Ja ...
- 实战Java虚拟机之四:提升性能,禁用System.gc() ?
今天开始实战Java虚拟机之四:"禁用System.gc()". 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟 ...
- 实战Java虚拟机之三“G1的新生代GC”
今天开始实战Java虚拟机之三:“G1的新生代GC”. 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实 ...
- 实战Java虚拟机之二“虚拟机的工作模式”
今天开始实战Java虚拟机之二:“虚拟机的工作模式”. 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实 ...
- 实战java虚拟机的学习计划图(看懂java虚拟机)
啥也不说了,实战java虚拟机,好好学习,天天向上!针对自己的软肋制定学习计划. 一部分内容看完,自己做的学习笔记和感想. 学java很简单,但懂java会有难度,如果你的工资还没超过1W,那是时候深 ...
- 实战Java虚拟机之中的一个“堆溢出处理”
从今天開始.我会发5个关于java虚拟机的小系列: 实战Java虚拟机之中的一个"堆溢出处理" 实战Java虚拟机之二"虚拟机的工作模式" 实战Java虚拟机之 ...
- 深入理解java虚拟机【内存溢出实例】
通过简单的小例子程序,演示java虚拟机各部分内存溢出情况: (1).java堆溢出: Java堆用于存储实例对象,只要不断创建对象,并且保证GC Roots到对象之间有引用的可达,避免垃圾收集器回收 ...
- 【java虚拟机】内存溢出与内存泄漏
作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/7354857.html 一.基本概念 内存溢出:简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提 ...
随机推荐
- PHP中的变量与常量详解
几乎所有的编程语言都会涉及到变量和常量这两个概念,PHP也不例外.本节将介绍PHP语言中的变量和常量的应用方法. 一.什么是变量和常量 在程序执行的过程中,变量存储的值可以随时改变,而常量存储的值是不 ...
- MySQL Cluster 集群简介
简介 MySQL集群是一种在无共享架构(SNA,Share Nothing Architecture)系统里应用内存数据库集群的技术.这种无共享的架构可以使得系统使用低廉的硬件获取高的可扩展性. My ...
- 签名、BOM头、编码、Windows记事本编码、java编码解码的那些事
对于Windows记事本: ANSI :GB2312 java中应使用GBK解码 Unicode :有签名的UTF-16LE java中应使用UTF-16解码 Unicode big endian : ...
- mac 下修改jenkins的 端口号
sudo defaults write /Library/Preferences/org.jenkins-ci httpPort 7070
- Google疯了,竟然这样!
导读 一个小问题:你每天做什么事?当然了,好多事情,但是我可以指出一件事,你几乎每天都会用 Google 搜索,我说的对吗?现在,如果你是一位 Linux 用户,这里有另外一个问题:如果你甚至不用离开 ...
- [BZOJ3173][Tjoi2013]最长上升子序列
[BZOJ3173][Tjoi2013]最长上升子序列 试题描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上 ...
- ASP.NET获取客户端的相关信息
/// <summary> /// 获取远程浏览器端 IP 地址 /// </summary> /// <returns> ...
- 使用jvisualvm.exe 的Btrace插件介绍/使用教程
一.背景 在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数.返回值.全局变量.堆栈信息等.为了获取这些数据信息,我们可以 通过改写代码,增加日志信息的打 ...
- squid介绍及其简单配置
squid的简单介绍 squid的概念 squid是一种用来缓存Internet数据的软件.接受来自人们需要下载的目标(object)的请求并适当的处理这些请求.也就是说,如果一个人想下载一web界面 ...
- c#关于类的继承
public class D { public virtual void Run(string name) { Console.WriteLine(name + ",good"); ...