设为首页 加入收藏

TOP

从几个sample来学习Java堆,方法区,Java栈和本地方法栈(一)
2014-11-24 10:46:15 】 浏览:3268
Tags:从几个 sample 学习 Java 方法 地方法

1)Java堆

所有对象的实例分配都在Java堆上分配内存,堆大小由-Xmx和-Xms来调节,sample如下所示:

[java]
public class HeapOOM {

static class OOMObject{}

/**
* @param args
*/
public static void main(String[] args) {
List list = new ArrayList();

while(true){
list.add(new OOMObject());
}
}

}

加上JVM参数-verbose:gc -Xms10M -Xmx10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError,就能很快报出OOM:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

并且能自动生成Dump。

2)方法区

方法区是存放虚拟机加载类的相关信息,如类、静态变量和常量,大小由-XX:PermSize和-XX:MaxPermSize来调节,类太多有可能撑爆永久带:

[java]
public class MethodAreaOOM {

static class OOMOjbect{}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
while(true){
Enhancer eh = new Enhancer();
eh.setSuperclass(OOMOjbect.class);
eh.setUseCache(false);
eh.setCallback(new MethodInterceptor(){

@Override
public Object intercept(Object arg0, Method arg1,
Object[] arg2, MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
return arg3.invokeSuper(arg0, arg2);
}

});
eh.create();
}
}

}

加上永久带的JVM参数:-XX:PermSize=10M -XX:MaxPermSize=10M,运行后会报如下异常:
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space

静态变量或常量也会有可能撑爆方法区:

[java]
public class ConstantOOM {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
List list = new ArrayList();
int i=0;
while(true){
list.add(String.valueOf(i++).intern());
}
}

}

同样加上JVM参数:-XX:PermSize=10M -XX:MaxPermSize=10M,运行后报如下异常:
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space

3)Java栈和本地方法栈

栈是存放线程调用方法时存储局部变量表,操作,方法出口等与方法执行相关的信息,栈大小由Xss来调节,方法调用层次太多会撑爆这个区域,samples如下所示:

[java]
package com.cutesource;

public class StackOOM {

/**
* @param args
*/

private int stackLength = 1;

public void stackLeak(){
stackLength++;
stackLeak();
}

public static void main(String[] args) throws Throwable{
// TODO Auto-generated method stub
StackOOM oom = new StackOOM();
try{
oom.stackLeak();
}catch(Throwable err){
System.out.println("Stack length:" + oom.stackLength);
throw err;
}

}

}

设置JVM参数:-Xss128k,报出异常:
Exception in thread "main" java.lang.StackOverflowError

打印出Stack length:1007,这里可以看出,在我的机器上128k的栈容量能承载深度为1007的方法调用。当然报这样的错很少见,一般只会出现无限循环的递归中,另外,线程太多也会占满栈区域:

[java]
package com.cutesource;

public class StackOOM {

/**
* @param args
*/

private int stackLength = 1;

private void dontStop(){
while(true){
try{Thread.sleep(1000);}catch(Exception err){}
}
}

public void stackLeakByThread(){
while(true){
Thread t = new Thread(new Runnable(){

@Override
public void run() {
// TODO

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Spring引用外部文件生成主键配置 下一篇com.taobao.api.ApiException: ja..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目