熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

發現Java虛擬機內存洩露問題

2013-11-23 19:33:19  來源: Java核心技術 
內存洩露問題對於程序來說是一個很難發現並且容易引起嚴重災害的事情Java一直以其垃圾回收機制為自豪那是否這種機制就是完美的呢

  常規理解上Java的內存管理機制是將局部變量保存在堆中當變量的作用域結束之後該變量所占用的內容會被自動回收不需要做任何特殊的處理比如下面的代碼




public class JavaMemory{
      private final int dataSize = (int) (RuntimegetRuntime()maxMemory() * );      
public void f(){
          {
              byte[] data = new byte[dataSize];
         }
          byte[] data = new byte[dataSize];
      }
      public static void main(String[] args) {
          JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();
          jmpf();
      }
  }

  在這個例子中方法f()裡定義了兩個局部變量變量data和data的作用域不同按照正常理解雖然兩各個數組所需要的內存之和已經超過了可用內存但是因為data會被及時回收不會出現內存溢出錯誤

  如果我們實際執行這個例子會發現出現了javalangOutOfMemoryError錯誤這是為什麼?如果在BEA或者IBM的虛擬機上測試過這個例子並不會出現錯誤也就是說SUN的JVM在內存回收機制上存在漏洞或者BUG

  這個問題該如何修正呢方法其實很簡單只需要在變量作用域結束之前將變量置為空就可以了修改之後的結果如下




public class JavaMemory{
      private final int dataSize = (int) (RuntimegetRuntime()maxMemory() * );      
public void f(){
          {
              byte[] data = new byte[dataSize];
              data = null;
          }
          byte[] data = new byte[dataSize];
      }
       public static void main(String[] args) {
          JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();
          jmpf();
      }
  }

  發現這個問題對於Java開發者來說也許會很緊張擔心自己的代碼是否會出現同樣問題大家盡可放心連續出現兩個變量占用內存之和超過內存限制的情況概率非常小並且在兩個變量之間如果定義了其他變量也不會出現這個問題如下面的代碼就不會出現問題




public class JavaMemory{
      private final int dataSize = (int) (RuntimegetRuntime()maxMemory() * );      
public void f(){
          {
              byte[] data = new byte[dataSize];
          }
      int i=;
          byte[] data = new byte[dataSize];
      }
       public static void main(String[] args) {
          JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();
          jmpf();
      }
  }
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27088.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.