老李案例分享:定位JAVA内存溢出
老李案例分享:定位JAVA内存溢出
poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。在poptest的loadrunner的培训中,为了提高学员性能优化的经验,加入了语言以及服务器方面的优化知识,为性能调优的能力打下基础。(大家对课程感兴趣,请加qq:564202718)
项目中最佳实践:
1. 编码规范认真执行。制定公司内部Java编码规范,让项目组成员遵守。
2. 单元测试要覆盖所有分支与边界条件。
3. 代码审查。代码写完了,找资深程序猿走读代码。
4. 利用测试人员的能动性。
问题提示:
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: PermGen space
解决方法:
a.java.lang.OutOfMemoryError: PermGen space :
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域, 这块内存主要是被JVM存放Class和Meta信息的,Class在被Load时就会被放到PermGen space中, 它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对 PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误。
通过上面的描述就可以得出:如果要加载的class与jar文件大小超过-XX:MaxPermSize就有可能会产生java.lang.OutOfMemoryError: PermGen space 。
-XX:MaxPermSize的大小要超过class与jar的大小。通常-XX:MaxPermSize为-Xmx的1/8。
b.java.lang.OutOfMemoryError: Java heap space:
虽然各种java虚拟机的实现机制不一,但是heap space内存溢出产生的原因相同:那就是堆内存不够虚拟机分配了。
内存分配机制与gc是有联系,内存不够分配时gc释放不了堆内存。释放不了内存是因为内存还在用。java对象产生的堆内存占用,只要其不再被继续引用gc是能够顺利回收的
问题的关键就找到了,当产生heap space内存溢出时,堆内存中对象数量过多的就可能是问题的根源了。例外的情况是,程序确实需要那么多内存,这时就要考虑增大堆内存。
辅助工具:
jdk自带两个可视化工具来定位问题:
jdk/jconsole.exe jdk/jvisualvm.exe
a.jconsole.exe可以查看本地以及远程主机上的java虚拟机的当前状况,这对服务器健康检查情况非常有用。如下图:

b. jvisualvm.exe可以用来查看分析内存转储文件;也可以用其做java虚拟机当前状况查看,但是jvisualvm.exe的侵入性非常强,一旦使用会严重影响应用性能。如下图:

下面写些代码来演示一下内存溢出的产生,堆转储文件的生成,堆内存的分析。
首先创建数据持有对象类:
package com.zas.jvm.om;
/**
* 数据对象
* @author zas
*/
public class DataObject {
//数据对象ID
private String id;
//数据对象内容
private String des;
public DataObject(String id, String des) {
super();
this.id = id;
this.des = des;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
@Override
public String toString() {
return "DataObject [id=" + id + ", des=" + des + "]";
}
/**
* @param args
*/
public static void main(String[] args) {
}
}
溢出演示代码
package com.zas.jvm.om;
import java.util.ArrayList;
import java.util.List;
public class OutMemeryTest {
List<DataObject> list = new ArrayList<DataObject>();
public void testOm(){
for (int i = 0; i < 100000; i++) {
DataObject data = new DataObject("id&"+i, "des:"+i);
list.add(data);
}
}
/**
* @param args
*/
public static void main(String[] args) {
OutMemeryTest omt = new OutMemeryTest();
for (int i = 0; i < 2; i++) {
omt.testOm();
}
System.out.println("DOne!");
try {
Thread.sleep(100000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行参数设置如下:-Xms64m -Xmx64m -XX:PermSize=8m -XX:MaxPermSize=8m
-XX:-HeapDumpOnOutOfMemoryError
见下图:

jvisualvm分析效果图:

从上图结合代码明显得出:com.zas.jvm.om.DataObject这个类的对象出了问题。
以上是一个演示问题产生及定位过程,生产环境的问题千奇百怪需要具体问题具体分析。
当堆内存巨大时可能要调整jdk\lib\visualvm\etc\visualvm.conf文件中的-xms -xmx大小来导入转储文件。
生产环境为linux的较多,可以借助jdk自带的jmap来转储堆内存文件来分析。
老李案例分享:定位JAVA内存溢出的更多相关文章
- 老李案例分享:MAT分析应用程序服务出现内存溢出过程
老李案例分享:MAT分析应用程序服务出现内存溢出过程 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的loa ...
- java内存溢出的解决思路
原文地址:https://www.cnblogs.com/200911/p/3965108.html 内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能 ...
- [转]Java内存溢出详解及解决方案
原文地址:http://blog.csdn.net/xianmiao2009/article/details/49254391 内存溢出与数据库锁表的问题,可以说是开发人员的噩梦,一般的程序异常,总是 ...
- Java内存溢出的详细解决方案
本文介绍了Java内存溢出的详细解决方案.本文总结内存溢出主要有两种情况,而JVM经常调用垃圾回收器解决内存堆不足的问题,但是有时仍会有内存不足的错误.作者分析了JVM内存区域组成及JVM设置虚拟内存 ...
- JAVA内存溢出解析(转)
JAVA内存溢出解析(转) 核心提示:原因有很多种,比如: 1.数据量过于庞大:死循环 :静态变量和静态方法过多:递归:无法确定是否被引用的对象: 2.虚拟机不回收内存(内存泄漏): 说白了就是程序运 ...
- 老李案例分享:Weblogic性能优化案例
老李案例分享:Weblogic性能优化案例 POPTEST的测试技术交流qq群:450192312 网站应用首页大小在130K左右,在之前的测试过程中,其百用户并发的平均响应能力在6.5秒,性能优化后 ...
- 定位JVM内存溢出问题思路总结
JVM的内存溢出问题,是个常见而有时候有非常难以定位的问题.定位内存溢出问题常见方法有很多,但是其实很多情况下可供你选择的有效手段非常有限.很多方法在一些实际场景下没有实用价值.这里总结下我的一些定位 ...
- 模拟Java内存溢出
本文通过修改虚拟机启动参数,来剖析常见的java内存溢出异常(基于jdk1.8). 修改虚拟机启动参数Java堆溢出虚拟机栈溢出方法区溢出本机直接内存溢出 修改虚拟机启动参数 这里我们使用的是ID ...
- Java内存溢出OutOfMemoryError的产生与排查
在java的虚拟机异常中,有两个异常是大家比较关心的,一个是StackOverflowError,另一个是OutOfMemoryError.今天我们就来看看OutOfMemoryError是怎么产生的 ...
随机推荐
- JavaScript截取字符串的Slice、Substring、Substr函数简单比较还有indexof函数应用
//截取字符,一看就明白!!! var str = "0123456789"; alert(str.substring(5)); 弹出 //56789 alert(str.subs ...
- devexpress表格gridcontrol实现分组,并根据分组计算总计及平均值
1.devexpress表格控件gridcontrol提供了强大的分组功能,你几乎不用写什么代码就可以实现一个分组功能,并且可根据分组计算总计和平均值.这里我例举了一个实现根据班级分组计算班级总人数, ...
- windows管道
匿名管道的使用 匿名管道主要用于本地父进程和子进程之间的通信, 在父进程中的话,首先是要创建一个匿名管道, 在创建匿名管道成功后,可以获取到对这个匿名管道的读写句柄, 然后父进程就可以向这个匿名管道中 ...
- 第34篇 再谈http协议
从打开一个网址说起 当在浏览器中输入一个网址的时候,浏览器会渲染出对应的网页的内容.作为web开发人员来说,应该知道这个过程: 当输入的一个网址为域名的时候,浏览器则根据本机的网关和DNS服务器来解析 ...
- .NET 知识整理笔记
本文纯属自己理解着写的,如果有什么错误或者不全面希望读者能够加以补充!~ 1.Web.Config配置文件的节点操作. 在Web.Config中写入. <configuration> &l ...
- JavaScript数据结构——栈的实现
栈(stack)是一种运算受限的线性表.栈内的元素只允许通过列表的一端访问,这一端被称为栈顶,相对地,把另一端称为栈底.装羽毛球的盒子是现实中常见的栈例子.栈被称为一种后入先出(LIFO,last-i ...
- Codevs2018 反病毒软件
2018 反病毒软件 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 查看运行结果 题目描述 Description 其实这个“反病毒软件”(Anti ...
- Visual Studio 2017 通过SSH 调试Linux 上.NET Core
Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Studio 2017 部署环境:Ubuntu ...
- 关于java泛型
<T> 代表的是泛型 ,实例化的时候将传入真正的数据类型,比如: public interface BaseProvider<T>{ public T test(); } 实例 ...
- ASP.NET脚本过滤-防止跨站脚本攻击(收集别人的)
ASP.Net 1.1后引入了对提交表单自动检查是否存在XSS(跨站脚本攻击)的能力.当用户试图用<xxxx>之类的输入影响页面返回结果的时候,ASP.Net的引擎会引发一个 HttpRe ...