日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JVM的內(nèi)存溢出異常

在Java虛擬機(jī)規(guī)范的描述中,除了PC(程序計數(shù)器)寄存器外,虛擬機(jī)內(nèi)存的其他幾個運(yùn)行時區(qū)域都有發(fā)生OutOfMemoryError異常的可能。當(dāng)發(fā)生OutOfMemoryError異常時,無法用try...catch捕捉。

創(chuàng)新互聯(lián)公司致力于互聯(lián)網(wǎng)網(wǎng)站建設(shè)與網(wǎng)站營銷,提供網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、網(wǎng)站開發(fā)、seo優(yōu)化、網(wǎng)站排名、互聯(lián)網(wǎng)營銷、小程序開發(fā)、公眾號商城、等建站開發(fā),創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)策劃專家,為不同類型的客戶提供良好的互聯(lián)網(wǎng)應(yīng)用定制解決方案,幫助客戶在新的全球化互聯(lián)網(wǎng)環(huán)境中保持優(yōu)勢。

在開始講解之前,在這里先簡單介紹下虛擬機(jī)啟動相關(guān)的一些內(nèi)存設(shè)置參數(shù)。因為OutOfMemoryError異常發(fā)生,與這些參數(shù)的設(shè)置密切相關(guān)。

舉例說明含義:

-Xss128k

每個線程的java棧大小,一個線程java棧所有棧幀大小總和***允許的尺寸128k。

-Xms128m

表示JVM Heap(堆內(nèi)存)最小尺寸128MB,初始分配

-Xmx512m

表示JVM Heap(堆內(nèi)存)***允許的尺寸256MB,按需分配。

-XX:PermSize=20M

設(shè)置方法區(qū)的初始大小

-XX:MaxPermSize=30M

設(shè)置方法區(qū)的***值

Java棧溢出

在Java虛擬機(jī)規(guī)范中,對這個區(qū)域規(guī)定了兩種異常狀況:StackOverflowError和OutOfMemoryError異常。

1.StackOverflowError異常

每當(dāng)java程序代碼啟動一個新線程時,Java虛擬機(jī)都會為它分配一個Java棧。Java棧以幀為單位保存線程的運(yùn)行狀態(tài)。當(dāng)線程調(diào)用java方法時,虛擬機(jī)壓入一個新的棧幀到該線程的java棧中。只要這個方法還沒有返回,它就一直存在。如果線程的方法嵌套調(diào)用層次太多(如遞歸調(diào)用),隨著java棧中幀的逐漸增多,最終會由于該線程java棧中所有棧幀大小總和大于-Xss設(shè)置的值,而產(chǎn)生StackOverflowError內(nèi)存溢出異常。例子如下:

 
 
 
  1. /**  
  2.   * VM Args: -Xss128k  
  3.   */ 
  4.  public class Test {  
  5.        
  6.      private int count = 0;  
  7.    
  8.      public static void main(String[] args) {  
  9.          new Test().method();  
  10.      }  
  11.        
  12.      public void method() {  
  13.          System.out.println(++count);  
  14.          method();  
  15.      }  
  16.    
  17.  } 

-Xss為128k。其中的一次測試結(jié)果為,當(dāng)count的值累加到2312時,發(fā)生如下異常:

 
 
 
  1. Exception in thread "main" java.lang.StackOverflowError  
  2.     at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:58)  
  3.     at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:392)  
  4.     at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:447)  
  5.     at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:544)  
  6.     at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:252)  
  7.     at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:106)  
  8.     at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)  
  9.     at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)  
  10.     at java.io.PrintStream.write(PrintStream.java:476)  
  11.     at java.io.PrintStream.print(PrintStream.java:547)  
  12.     at java.io.PrintStream.println(PrintStream.java:686)  
  13.     at jvm.Test.method(Test.java:17) 

修改-Xss為1280k。其中的一次測試結(jié)果為,當(dāng)count的值累加到26888時,發(fā)生StackOverflowError異常。隨著-Xss參數(shù)值的增大,可以嵌套的方法調(diào)用層次也相應(yīng)增加。

綜上所述,StackOverflowError異常是由于方法調(diào)用的層次太深,最終導(dǎo)致為某個線程分配的所有棧幀大小總和大于-Xss設(shè)置的值,從而發(fā)生StackOverflowError異常。

2.OutOfMemoryError異常

java程序代碼啟動一個新線程時,沒有足夠的內(nèi)存空間為該線程分配java棧(一個線程java棧的大小由-Xss參數(shù)確定),jvm則拋出OutOfMemoryError異常。例子如下:

 
 
 
  1. /**  
  2.   * VM Args: -Xss128k  
  3.   */ 
  4.  public class Test {  
  5.        
  6.      public static void main(String[] args) {  
  7.          int count = 0;  
  8.          while (true) {  
  9.              Thread thread = new Thread(new Runnable() {  
  10.                  public void run() {  
  11.                      while (true) {  
  12.                          try {  
  13.                              Thread.sleep(5000);  
  14.                          } catch (Exception e) {}  
  15.                      }  
  16.                  }  
  17.              });    
  18.              thread.start();  
  19.              System.out.println(++count);  
  20.          }  
  21.      }  
  22.    
  23.  } 

-Xss為128k。其中的一次測試結(jié)果為,當(dāng)count的值累加到11887時,發(fā)生如下異常:

 
 
 
  1. Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread  
  2.     at java.lang.Thread.start0(Native Method)  
  3.     at java.lang.Thread.start(Thread.java:640)  
  4.     at jvm.Test.main(Test.java:20) 

修改-Xss為1280k。其中的一次測試結(jié)果為,當(dāng)count的值累加到1270時,發(fā)生OutOfMemoryError異常。隨著-Xss參數(shù)值的增大,java程序可以創(chuàng)建的總線程數(shù)越少。

Java堆溢出

Java堆用于儲存對象實例。當(dāng)需要為對象實例分配內(nèi)存,而堆的內(nèi)存占用又已經(jīng)達(dá)到-Xmx設(shè)置的***值。將會拋出OutOfMemoryError異常。例子如下:

 
 
 
  1. /**  
  2.   * VM Args: -Xmx5m  
  3.   */ 
  4.  public class Test {  
  5.        
  6.      public static void main(String[] args) {  
  7.          int count = 0;  
  8.          List list = new ArrayList();  
  9.          while (true) {  
  10.              list.add(new Object());  
  11.              System.out.println(++count);  
  12.          }  
  13.      }  
  14.    
  15.  } 
  16. -Xmx為5m。其中的一次測試結(jié)果為,當(dāng)count的值累加到297868時,發(fā)生如下異常:

     
     
     
    1. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space  
    2.     at java.util.Arrays.copyOf(Arrays.java:2760)  
    3.     at java.util.Arrays.copyOf(Arrays.java:2734)  
    4.     at java.util.ArrayList.ensureCapacity(ArrayList.java:167)  
    5.     at java.util.ArrayList.add(ArrayList.java:351)  
    6.     at jvm.Test.main(Test.java:15) 

    修改-Xmx為10m。其中的一次測試結(jié)果為,當(dāng)count的值累加到670205時,發(fā)生OutOfMemoryError異常。隨著-Xmx參數(shù)值的增大,java堆中可以存儲的對象也越多。

    方法區(qū)溢出

    方法區(qū)用于存放java類型的相關(guān)信息,如類名、訪問修飾符、常量池、字段描述、方法描述等。在類裝載器加載class文件到內(nèi)存的過程中,虛擬機(jī)會提取其中的類型信息,并將這些信息存儲到方法區(qū)。當(dāng)需要存儲類信息而方法區(qū)的內(nèi)存占用又已經(jīng)達(dá)到-XX:MaxPermSize設(shè)置的***值。將會拋出OutOfMemoryError異常。對于這種情況的測試,基本的思路是運(yùn)行時產(chǎn)生大量的類去填滿方法區(qū),直到溢出。這里需要借助CGLib直接操作字節(jié)碼運(yùn)行時,生成了大量的動態(tài)類。例子如下:

     
     
     
    1. /**  
    2.    * VM Args: -XX:MaxPermSize=50M  
    3.    */ 
    4.   public class Test {  
    5.         
    6.       public static void main(String[] args) {  
    7.           int count = 0;  
    8.           while (true) {  
    9.                Enhancer enhancer = new Enhancer();  
    10.                enhancer.setSuperclass(Test.class);  
    11.                enhancer.setUseCache(false);  
    12.                enhancer.setCallback(new MethodInterceptor() {  
    13.                   public Object intercept(Object obj, Method method, Object[] args,   
    14.                     MethodProxy proxy) throws Throwable {  
    15.                       return proxy.invoke(obj, args);  
    16.                   }  
    17.                });  
    18.                enhancer.create();  
    19.                System.out.println(++count);  
    20.           }  
    21.       }  
    22.     
    23.   } 

    -XX:MaxPermSize為50m。其中的一次測試結(jié)果為,當(dāng)count的值累加到3953時,發(fā)生如下異常:

     
     
     
    1. Caused by: java.lang.OutOfMemoryError: PermGen space  
    2.     at java.lang.ClassLoader.defineClass1(Native Method)  
    3.     at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)  
    4.     at java.lang.ClassLoader.defineClass(ClassLoader.java:615)  
    5.     ... 8 more 

    修改-XX:MaxPermSize為100m。其中的一次測試結(jié)果為,當(dāng)count的值累加到8022時,發(fā)生OutOfMemoryError異常。隨著-XX:MaxPermSize參數(shù)值的增大,java方法區(qū)中可以存儲的類型數(shù)據(jù)也越多。

    相關(guān)的參考資料:

    1.深入Java虛擬機(jī)(原書第2版)

    2.深入理解Java虛擬機(jī):JVM高級特性與***實踐

    3.互聯(lián)網(wǎng)相關(guān)的文章


    新聞標(biāo)題:JVM的內(nèi)存溢出異常
    網(wǎng)站鏈接:http://www.5511xx.com/article/cccsdoj.html