尊龙游戏旗舰厅官网
收集整理的这篇文章主要介绍了
从几个sample来学习java堆,方法区,java栈和本地方法栈
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
2019独角兽企业重金招聘python工程师标准>>>
最近在看《深入理解java虚拟机》,书中给了几个例子,比较好的说明了几种oom(outofmemory)产生的过程,大部分的程序员在写程序时不会太关注java运行时数据区域的结构:
感觉有必要通过几个实在的例子来加深对这几个区域的了解
1)java堆
所有对象的实例分配都在java堆上分配内存,堆大小由-xmx和-xms来调节,sample如下所示:
[java] view plain copy print ?
public class heapoom { static class oomobject{} /** * @param args */ public static void main(string[] args) { list list = new arraylist(); while(true){ list.add(new oomobject()); } } } 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] view plain copy print ? 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(); } } } public class methodareaoom {static class oomojbect{}/*** @param args*/public static void main(string[] args) {// todo auto-generated method stubwhile(true){enhancer eh = new enhancer();eh.setsuperclass(oomojbect.class);eh.setusecache(false);eh.setcallback(new methodinterceptor(){@overridepublic object intercept(object arg0, method arg1,object[] arg2, methodproxy arg3) throws throwable {// todo auto-generated method stubreturn arg3.invokesuper(arg0, arg2);}});eh.create();}}} 加上永久带的jvm参数:-xx:permsize=10m -xx:maxpermsize=10m,运行后会报如下异常: exception in thread "main" java.lang.outofmemoryerror: permgen space
静态变量或常量也会有可能撑爆方法区:
[java] view plain copy print ? 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()); } } } public class constantoom {/*** @param args*/public static void main(string[] args) {// todo auto-generated method stublist 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] view plain copy print ? 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; } } } 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 stubstackoom 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] view plain copy print ? 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 auto-generated method stub dontstop(); } }); t.start(); stacklength ; } } public static void main(string[] args) throws throwable{ // todo auto-generated method stub stackoom oom = new stackoom(); try{ oom.stackleakbythread(); }catch(throwable err){ system.out.println("stack length:" oom.stacklength); throw err; } } } 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(){@overridepublic void run() {// todo auto-generated method stubdontstop();}});t.start();stacklength ;}}public static void main(string[] args) throws throwable{// todo auto-generated method stubstackoom oom = new stackoom();try{oom.stackleakbythread();}catch(throwable err){system.out.println("stack length:" oom.stacklength);throw err;}}} 报出异常:exception in thread "main" java.lang.outofmemoryerror:unable to create new native thread 不过在windows上运行这个例子要小心,会出现系统假死的情况,有可能需要重启机器才行。
以上几个例子虽然比较简单,但能很好帮助普通的程序员更加直观的了解java堆 ,方法区 ,java栈和本地方法栈 。
转载于:https://my.oschina.net/chaos777/blog/308525
与50位技术专家面对面 20年技术见证,附赠技术全景图
总结
以上是尊龙游戏旗舰厅官网 为你收集整理的从几个sample来学习java堆,方法区,java栈和本地方法栈 的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得尊龙游戏旗舰厅官网 网站内容还不错,欢迎将尊龙游戏旗舰厅官网 推荐给好友。