发现Java虚拟机内存泄露问题

来源:计算机等级考试    发布时间:2012-08-29    计算机等级考试视频    评论

   内存泄露问题对于程序来说,是一个很难发现,并且容易引起严重灾害的事情。Java一直以其垃圾回收机制为自豪,那是否这种机制就是完美的呢。

  常规理解上,Java的内存管理机制是将局部变量保存在堆中,当变量的作用域结束之后,该变量所占用的内容会被自动回收。不需要做任何特殊的处理。比如下面的代码:

public class JavaMemory{
      
private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);      
public void f(){
          {
              
byte[] data1 = new byte[dataSize];
         }
          
byte[] data2 = new byte[dataSize];
      }
      
public static void main(String[] args) {
          JavaMemoryPuzzle jmp
= new JavaMemoryPuzzle();
          jmp.f();
      }
  }

  在这个例子中,方法f()里定义了两个局部变量,变量data1和data2的作用域不同。按照正常理解,虽然两各个数组所需要的内存之和已经超过了可用内存,但是因为data1会被及时回收,不会出现内存溢出错误。

  如果我们实际执行这个例子,会发现出现了java.lang.OutOfMemoryError错误。这是为什么?如果在BEA或者IBM的虚拟机上测试过这个例子,并不会出现错误。也就是说,SUN的JVM在内存回收机制上存在漏洞或者BUG。

  这个问题该如何修正呢,方法其实很简单。只需要在变量作用域结束之前,将变量置为空就可以了。修改之后的结果如下:

public class JavaMemory{
      
private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);      
public void f(){
          {
              
byte[] data1 = new byte[dataSize];
              data1
= null;
          }
          
byte[] data2 = new byte[dataSize];
      }
      
public static void main(String[] args) {
          JavaMemoryPuzzle jmp
= new JavaMemoryPuzzle();
          jmp.f();
      }
  }

  发现这个问题,对于Java开发者来说也许会很紧张,担心自己的代码是否会出现同样问题。大家尽可放心,连续出现两个变量占用内存之和超过内存限制的情况概率非常小。并且在两个变量之间,如果定义了其他变量也不会出现这个问题。如下面的代码就不会出现问题:

public class JavaMemory{
      
private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);      
public void f(){
          {
              
byte[] data1 = new byte[dataSize];
          }
      
int i=1;
          
byte[] data2 = new byte[dataSize];
      }
      
public static void main(String[] args) {
          JavaMemoryPuzzle jmp
= new JavaMemoryPuzzle();
          jmp.f();
      }
  }

  编辑特别推荐:

  Java编程语言中notify和wait的具体应用

视频学习

我考网版权与免责声明

① 凡本网注明稿件来源为"原创"的所有文字、图片和音视频稿件,版权均属本网所有。任何媒体、网站或个人转载、链接转贴或以其他方式复制发表时必须注明"稿件来源:我考网",违者本网将依法追究责任;

② 本网部分稿件来源于网络,任何单位或个人认为我考网发布的内容可能涉嫌侵犯其合法权益,应该及时向我考网书面反馈,并提供身份证明、权属证明及详细侵权情况证明,我考网在收到上述法律文件后,将会尽快移除被控侵权内容。

最近更新

社区交流

考试问答