Hotspot内存溢出测试
一、堆溢出
在执行代码时通过设置堆的最小值-Mms以及堆的最大值-Mmx来控制堆的大小,-XX参数dump出堆内存快照以便对内存溢出进行分析。通过创建大量对象来使堆溢出,当堆内存溢出时会提示OutOfMemeoryError:Java heap space信息。
import java.util.List;
import java.util.ArrayList; public class HeapOOM {
static class OOMObject{} public static void main(String[] args) {
List<OOMObject> list =new ArrayList<OOMObject>();
while(true){
list.add(new OOMObject());
}
}
}

二、栈溢出
栈溢出的原因主要是方法调用嵌套太深超出了虚拟机所允许的最大深度,这时会出现StackOverflowError异常。
import java.lang.Throwable;
public class JavaVMStackSOF{
private int stackLength=1;
public void stackLeak(){
stackLength ++;
stackLeak();
}
public static void main(String[] args) {
JavaVMStackSOF sof = new JavaVMStackSOF();
try{
sof.stackLeak();
}catch(Throwable e){
System.out.println("stack length: " + sof.stackLength);
throw e;
}
}
}
指定栈的大小最多为128kb,如果在openJDK下,这个值会引起虚拟机报错


在执行java代码时会启动JVM,JVM对于操作系统来说是一个普通的进程。因为使用到了虚拟内存映射技术。JVM在自己看了物理机上只存在自己和OS。我们假定物理内存4G,操作系统使用了1G,则JVM可用空间为3G。这3G中除去方法区和堆区(这两个区域java线程共享),剩下的区域(虚拟机栈、本地方法栈和程序计数器)是每个线程独占的。程序计数器所占区域很小,而在Hotspot中虚拟机栈和本地方法栈是被融合在一起的。剩余区域固定、栈大小固定,则在JVM虚拟中可以创建的线程数量是固定的。所以,当我们在创建线程时如果出现内存溢出、无法创建更多的线程的错误时,就应该注意到线程数应该达到上限了。在这种情况下仍需要创建更多的线程,要的增大物理内存,要么减少栈的大小。
方法区溢出
方法区存放的是与类相关的信息,如类名、访问修饰符、常量池、字段描述、方法描述等。本来可以通过创建大量的字符串常量来增大常量池从而导致方法区溢出。JAVA6可以使用上述方法来达到测试效果,但是由于JAVA7的优化,使得在常量存储有了改进。这里只能动态创建大量的类来使常量区溢出。动态创建类时使用到了CGLib库,该库是用来实现代理的类的。这里使用它来创建大量的类。
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; public class JavaMethodAreaOOM{
public static void main(String[] args) {
while(true){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor(){
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
}
});
enhancer.create();
}
} static class OOMObject{}
}
使用JDK7运行时出现的异常,这里只显示了出现了内存溢出

使用JDK6时出现的异常,这里显示出是永久区出现异常

在运行时通过PermSize以及MaxPermSize来控制方法区的大小,在JDK6中,方法区中的内容也是通过GC来管理的,这块区域被划分为永久代,所以即使被GC管理也不会出现回收的状况。但是在JDK7中将永久代弱化了,所以在JDK7上运行时会并没有出现永久代区域溢出。
总结
通过上面的测试,可以对java中的内存分布有个了解。并且为内存溢出也提供了分析的依据。在使用java虚拟机时,通过调整上面的几个参数,可以让虚拟机有个更好的运行状态。
Hotspot内存溢出测试的更多相关文章
- 【深入Java虚拟机】之一:Java内存模型与内存溢出
[深入Java虚拟机]之:Java内存区域与内存溢出 高速缓存模型如下: ----------------------------------------------------分割线-------- ...
- 【深入Java虚拟机】之三:内存溢出
为了更直接的了解各区域,下面我们来看几个示例. 1.Java 堆溢出 下面的程中我们限制Java 堆的大小为20MB,不可扩展(将堆的最小值-Xms 参 数与最大值-Xmx 参数设置为一样即可避免堆自 ...
- php导出超大csv导出方法,读取超大文件或者接受超大数组,防止内存溢出
基本思路就是,知道总数之后分割成2万一个数组进行查询,最后独立写入csv,避免数据过大导致溢出 速度还不错,在php7下,机器I5 8G内存,128G,SSD,52W多条,大概也就30秒,出来整个文件 ...
- JVM异常之:直接内存溢出
示例: package com.dxz.jvm; import java.lang.reflect.Field; import sun.misc.Unsafe; /** * @Described:直接 ...
- JAVA:测试java虚拟机支持的最大内存 Xmx 值?Tomcat 内存溢出?(转)
如下命令,即可测试:不断调整n的值,windows上32位的1.6x为: 1610m java -Xmx1610M -versionjava -Xmx1610m -version 网摘的tomcat内 ...
- Android 内存溢出管理与测试
今天发现正在做的项目,时不时的会报错:dalvikvm heap out of memory on a 7458832-byte allocation (堆分配的内存溢出) 为什么会内存溢出呢?我以前 ...
- Java内存区域与内存溢出异常--HotSpot虚拟机对象探秘
以常用的HotSpot和常用的Java堆为例,深入探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程 1.对象的创建 ①虚拟机遇到一条new指令后,首先将去检查这个指令的参数是否能够在 ...
- java虚拟机(十)--性能监控工具测试内存溢出和死锁基本思路
在之前就曾经简单介绍过jdk自带的性能检测工具,但是只是很入门的内容.没有真正的用过都是白扯了,面试的时候也说不过去,更别提真正 在生产环境去解决问题,所以这里我们学习一下真正解决问题的过程,最起码面 ...
- 记录:测试本机下使用 GPU 训练时不会导致内存溢出的最大参数数目
本机使用的 GPU 是 GeForce 840M,2G 显存,本机内存 8G. 试验时,使用 vgg 网络,调整 vgg 网络中的参数,使得使用对应的 batch_size 时不会提示内存溢出.使用的 ...
随机推荐
- my_strlen()
int my_strlen(const char* S){ int i=0; while('\0'!=*(S+i)){ i++; } return i; }
- day 2 系统分区 扩展.md
1.分区类型 主分区: 最多只能有四个. 扩展分区: 最多只能有一个. 主分区加扩展分区最多有4个. 不能写入数据,只能包含逻辑分区. 逻辑分区 2.格式化 格式化(高级格式化)又称逻辑格式化,它是指 ...
- php魔术方法罗列
##__sleep() 和 __wakeup() 当序列化(serialize)对象时,PHP 将试图在序列动作之前调用该对象的成员函数 __sleep() .__sleep() 方法常用于提交未提交 ...
- html5新增及删除标签
一.新增标签 有一种划分为,功能性标签[html5新增,如canvas,旧浏览器没有]和语义性标签[如header等只是增强语义,没有新功能].下面按照分几个小类来说. 1.结构标签 新增的结构标签, ...
- 突然发现这周有点忙。。着玩-PHP进阶
hi 周二才,不过我突然意识到这周有点忙着玩的感觉,还是很期待的——今天下午去市里,晚上回来看电影,明晚聚餐吃火锅,后天下午拍短片,晚上可能要打球,周五,嗯,就到周五了.虽然这样下去连怎么写(bian ...
- 深入理解FTP协议
文件传输协议FTP(File Transfer Protocol)是因特网中使用最广泛的文件传输协议.FTP使用交互式的访问,允许客户指定文件的类型和格式(如指明是否使用ASCII码),并允许文件具有 ...
- Protobuf语言指南(转)
Protobuf语言指南 l 定义一个消息(message)类型 l 标量值类型 l Optional 的字段及默认值 l 枚举 l 使用其他消息类型 l 嵌套类型 l 更新一个消息类型 ...
- Apache http Server 2.4 安装与配置
前言 Apache官网从2.2之后,不再提供windows的msi或exe安装版本,现在Apache http Server有两个分支2.2及2.4 注意事项 如果之前有安装2.2的版本,请先卸载 A ...
- oracl中的集合操作符
1:union(并集) union连接两条sql语句,并且去除两条sql语句重复的记录 2.union all(并集) 接两句sql语句,两句sql语句的和不用去掉重复的记录. 3:inter ...
- 理解android.intent.action.MAIN 与 android.intent.category.LAUNCHER
刚才看了一下sundy的视频<LLY110426_Android应用程序启动>,里面讲到luncher这个activity通过获取应用程序信息来加载应用程序,显示给用户,其中就是通过一个应 ...