日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

从几个sample来学习Java堆,方法区,Java栈和本地方法栈

發(fā)布時(shí)間:2025/1/21 java 93 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从几个sample来学习Java堆,方法区,Java栈和本地方法栈 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

最近在看《深入理解Java虛擬機(jī)》,書(shū)中給了幾個(gè)例子,比較好的說(shuō)明了幾種OOM(OutOfMemory)產(chǎn)生的過(guò)程,大部分的程序員在寫(xiě)程序時(shí)不會(huì)太關(guān)注Java運(yùn)行時(shí)數(shù)據(jù)區(qū)域的結(jié)構(gòu):

感覺(jué)有必要通過(guò)幾個(gè)實(shí)在的例子來(lái)加深對(duì)這幾個(gè)區(qū)域的了解

1)Java堆

所有對(duì)象的實(shí)例分配都在Java堆上分配內(nèi)存,堆大小由-Xmx和-Xms來(lái)調(diào)節(jié),sample如下所示:

[java] view plain copy print ?
  • public class HeapOOM {
  • static class OOMObject{}
  • /**
  • * @param args
  • */
  • public static void main(String[] args) {
  • List<OOMObject> list = new ArrayList<OOMObject>();
  • while(true){
  • list.add(new OOMObject());
  • }
  • }
  • }
  • public class HeapOOM {static class OOMObject{}/*** @param args*/public static void main(String[] args) {List<OOMObject> list = new ArrayList<OOMObject>();while(true){list.add(new OOMObject());}}}
    加上JVM參數(shù)-verbose:gc -Xms10M -Xmx10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError,就能很快報(bào)出OOM:

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

    并且能自動(dòng)生成Dump。

    2)方法區(qū)

    方法區(qū)是存放虛擬機(jī)加載類(lèi)的相關(guān)信息,如類(lèi)、靜態(tài)變量和常量,大小由-XX:PermSize和-XX:MaxPermSize來(lái)調(diào)節(jié),類(lèi)太多有可能撐爆永久帶:

    [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參數(shù):-XX:PermSize=10M -XX:MaxPermSize=10M,運(yùn)行后會(huì)報(bào)如下異常:

    Exception in thread "main" java.lang.OutOfMemoryError: PermGen space

    靜態(tài)變量或常量也會(huì)有可能撐爆方法區(qū):

    [java] view plain copy print ?
  • public class ConstantOOM {
  • /**
  • * @param args
  • */
  • public static void main(String[] args) {
  • // TODO Auto-generated method stub
  • List<String> list = new ArrayList<String>();
  • 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<String> list = new ArrayList<String>();int i=0;while(true){list.add(String.valueOf(i++).intern());}}}
    同樣加上JVM參數(shù):-XX:PermSize=10M -XX:MaxPermSize=10M,運(yùn)行后報(bào)如下異常:

    Exception in thread "main" java.lang.OutOfMemoryError: PermGen space

    3)Java棧和本地方法棧

    棧是存放線程調(diào)用方法時(shí)存儲(chǔ)局部變量表,操作,方法出口等與方法執(zhí)行相關(guān)的信息,棧大小由Xss來(lái)調(diào)節(jié),方法調(diào)用層次太多會(huì)撐爆這個(gè)區(qū)域,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;}}}
    設(shè)置JVM參數(shù):-Xss128k,報(bào)出異常:

    Exception in thread "main" java.lang.StackOverflowError

    打印出Stack length:1007,這里可以看出,在我的機(jī)器上128k的棧容量能承載深度為1007的方法調(diào)用。當(dāng)然報(bào)這樣的錯(cuò)很少見(jiàn),一般只會(huì)出現(xiàn)無(wú)限循環(huán)的遞歸中,另外,線程太多也會(huì)占滿(mǎn)棧區(qū)域:

    [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;}}}
    報(bào)出異常:Exception in thread "main" java.lang.OutOfMemoryError:unable to create new native thread

    不過(guò)在windows上運(yùn)行這個(gè)例子要小心,會(huì)出現(xiàn)系統(tǒng)假死的情況,有可能需要重啟機(jī)器才行。

    以上幾個(gè)例子雖然比較簡(jiǎn)單,但能很好幫助普通的程序員更加直觀的了解Java堆方法區(qū)Java棧和本地方法棧

    轉(zhuǎn)載于:https://my.oschina.net/Chaos777/blog/308525

    與50位技術(shù)專(zhuān)家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的从几个sample来学习Java堆,方法区,Java栈和本地方法栈的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。