欢迎访问 生活随笔!

尊龙游戏旗舰厅官网

当前位置: 尊龙游戏旗舰厅官网 > 编程语言 > java >内容正文

java

从几个sample来学习java堆,方法区,java栈和本地方法栈 -尊龙游戏旗舰厅官网

发布时间:2025/1/21 java 25 豆豆
尊龙游戏旗舰厅官网 收集整理的这篇文章主要介绍了 从几个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栈和本地方法栈的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得尊龙游戏旗舰厅官网网站内容还不错,欢迎将尊龙游戏旗舰厅官网推荐给好友。

    网站地图