一、堆溢出


在执行代码时通过设置堆的最小值-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. 在Hekaton里,正确选择哈希存储桶数

    今天我使用2048的桶数的哈希索引,往Hakaton里插入100万的记录,测试下在哈希桶数里,哈希冲突(Hash Collision)是如何影响Hekaton的工作量——结果非常非常有意思.首先我想介 ...

  2. android Java instanceof关键字

    instanceof是Java的一个二元操作符,和==,>,<是同一类东东.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回boo ...

  3. node js学习(二)——REPL(交互式解释器)

    1.简介 Node.js REPL(Read Eval Print Loop:交互式解释器) 表示一个电脑的环境,类似 Window 系统的终端或 Unix/Linux shell,我们可以在终端中输 ...

  4. Sql server2012连接Sql server 2008时出现的问题:已成功与服务器建立连接,但在登陆过程中发生错误。(provider:SSL Provider,error:0-接收到的消息异常,或格式不正确。)

    以前连接是正常的,就这两天连不上了.(没有耐心的直接看末尾解决办法) 错误消息如下: 1.尝试读取或写入受保护的内存.这通常指示其他内存已损坏.(System.Data) 2.已成功与服务器建立连接, ...

  5. Neutron VxLAN + Linux Bridge 环境中的网络 MTU

    1. 基础知识 1.1 MTU   一个网络接口的 MTU 是它一次所能传输的最大数据块的大小.任何超过MTU的数据块都会在传输前分成小的传输单元.MTU 有两个测量层次:网络层和链路层.比如,网络层 ...

  6. 学习cocos 空程序

    今天开始学习cocos代码,首先研究源码中的空程序. 在这个程序中,在main函数中,创建了一个Application: int APIENTRY _tWinMain(HINSTANCE hInsta ...

  7. JavaScript Number 对象

    JavaScript Number 对象 Number 对象 Number 对象是原始数值的包装对象. Number 创建方式 new Number(). 语法 var num = new Numbe ...

  8. C#实现php的hash_hmac函数

    from:http://blog.csdn.net/ciaos/article/details/12618487 PHP代码示例如下 <?php         $res1 = hash_hma ...

  9. wget: unable to resolve host address的解决方法

    摘要:wget:无法解析主机地址.这就能看出是DNS解析的问题. wget:无法解析主机地址.这就能看出是DNS解析的问题. 解决办法: 登入root(VPS).进入/etc/resolv.conf. ...

  10. NFine的后台源码

    Chloe官网及基于NFine的后台源码毫无保留开放   扯淡 经过不少日夜的赶工,Chloe 的官网于上周正式上线.上篇博客中LZ说过要将官网以及后台源码都会开放出来,为了尽快兑现我说过的话,趁周末 ...