一、堆溢出


在执行代码时通过设置堆的最小值-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内存溢出测试的更多相关文章

  1. 【深入Java虚拟机】之一:Java内存模型与内存溢出

    [深入Java虚拟机]之:Java内存区域与内存溢出 高速缓存模型如下: ----------------------------------------------------分割线-------- ...

  2. 【深入Java虚拟机】之三:内存溢出

    为了更直接的了解各区域,下面我们来看几个示例. 1.Java 堆溢出 下面的程中我们限制Java 堆的大小为20MB,不可扩展(将堆的最小值-Xms 参 数与最大值-Xmx 参数设置为一样即可避免堆自 ...

  3. php导出超大csv导出方法,读取超大文件或者接受超大数组,防止内存溢出

    基本思路就是,知道总数之后分割成2万一个数组进行查询,最后独立写入csv,避免数据过大导致溢出 速度还不错,在php7下,机器I5 8G内存,128G,SSD,52W多条,大概也就30秒,出来整个文件 ...

  4. JVM异常之:直接内存溢出

    示例: package com.dxz.jvm; import java.lang.reflect.Field; import sun.misc.Unsafe; /** * @Described:直接 ...

  5. JAVA:测试java虚拟机支持的最大内存 Xmx 值?Tomcat 内存溢出?(转)

    如下命令,即可测试:不断调整n的值,windows上32位的1.6x为: 1610m java -Xmx1610M -versionjava -Xmx1610m -version 网摘的tomcat内 ...

  6. Android 内存溢出管理与测试

    今天发现正在做的项目,时不时的会报错:dalvikvm heap out of memory on a 7458832-byte allocation (堆分配的内存溢出) 为什么会内存溢出呢?我以前 ...

  7. Java内存区域与内存溢出异常--HotSpot虚拟机对象探秘

    以常用的HotSpot和常用的Java堆为例,深入探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程 1.对象的创建 ①虚拟机遇到一条new指令后,首先将去检查这个指令的参数是否能够在 ...

  8. java虚拟机(十)--性能监控工具测试内存溢出和死锁基本思路

    在之前就曾经简单介绍过jdk自带的性能检测工具,但是只是很入门的内容.没有真正的用过都是白扯了,面试的时候也说不过去,更别提真正 在生产环境去解决问题,所以这里我们学习一下真正解决问题的过程,最起码面 ...

  9. 记录:测试本机下使用 GPU 训练时不会导致内存溢出的最大参数数目

    本机使用的 GPU 是 GeForce 840M,2G 显存,本机内存 8G. 试验时,使用 vgg 网络,调整 vgg 网络中的参数,使得使用对应的 batch_size 时不会提示内存溢出.使用的 ...

随机推荐

  1. QT学习第1天

    QT学习第一天  坚持住!! 一 Qt概述 1.Qt发展历史 (1)1991年诞生(Haavard Nord/Eirik Chambe-Eng), (2)1994年创立Troll Tech(奇趣科技) ...

  2. 3.10.17 procfs示例

    /* *    wesley *    the linux module sample of procfs *     *    wesley for testing *    2013-12-23 ...

  3. NServiceBus 更换服务名及队列名称

    可以通过起动时的参数处理 NServiceBus.Host.exe /serviceName:”服务名称” /endpointName:”默认队列名称”

  4. Azure Linux VM Swap 分区

    默认情况下,Windows Azure上的Linux VM是没有Swap分区的.下面我们以Ubuntu为例,为Windows Azure上的Linux虚拟机创建Swap分区. Windows Azur ...

  5. WinCE及Windows软件开发相关书籍转让

    从开始做WinCE开发到现在已经十多年了,最初可以学习和参考的资料并不多,那时候还没有Stack Overflow,Google也还可以正常访问.遇到问题时,一般都在Google Groups的mic ...

  6. 【原创Android游戏】--猜数字游戏Version 0.1

    想当年高中时经常和小伙伴在纸上或者黑板上或者学习机上玩猜数字的游戏,在当年那个手机等娱乐设备在我们那还不是很普遍的时候是很好的一个消遣的游戏,去年的时候便写了一个Android版的猜数字游戏,只是当时 ...

  7. Codeforces Round #286 Div.1 A Mr. Kitayuta, the Treasure Hunter --DP

    题意:0~30000有30001个地方,每个地方有一个或多个金币,第一步走到了d,步长为d,以后走的步长可以是上次步长+1,-1或不变,走到某个地方可以收集那个地方的财富,现在问走出去(>300 ...

  8. VIJOS P1037搭建双塔[DP]

    描述 2001年9月11日,一场突发的灾难将纽约世界贸易中心大厦夷为平地,Mr. F曾亲眼目睹了这次灾难.为了纪念“9?11”事件,Mr. F决定自己用水晶来搭建一座双塔. Mr. F有N块水晶,每块 ...

  9. 第64课 C++中的异常处理(上)

    1. C++内置的异常处理:try-catch (1)try语句处理正常代码逻辑 (2)catch语句处理异常情况 (3)try语句中的异常由对应的catch语句处理,如果对应的catch中没有处理该 ...

  10. Linux下mysql新建账号及权限设置

    http://www.cnblogs.com/eczhou/archive/2012/07/12/2588187.html 1.权限赋予 说明:mysql部署在服务器A上,内网上主机B通过客户端工具连 ...