`

转:并非非常完美 发现Java虚拟机内存泄露问题

    博客分类:
  • java
 
阅读更多

并非非常完美 发现Java虚拟机内存泄露问题

2010-06-01 10:09作者:天极网开发频道出处:天极网软件频道责任编辑:郑重

 
 

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

  1. public class JavaMemory{  
  2.     private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);  
  3.     public void f(){  
  4.         {  
  5.             byte[] data1 = new byte[dataSize];  
  6.         }  
  7.         byte[] data2 = new byte[dataSize];  
  8.     }  
  9.  
  10.     public static void main(String[] args) {  
  11.         JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();  
  12.         jmp.f();  
  13.     }  

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

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

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

  1. public class JavaMemory{  
  2.     private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);  
  3.     public void f(){  
  4.         {  
  5.             byte[] data1 = new byte[dataSize];  
  6.             data1 = null;  
  7.         }  
  8.         byte[] data2 = new byte[dataSize];  
  9.     }  
  10.  
  11.     public static void main(String[] args) {  
  12.         JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();  
  13.         jmp.f();  
  14.     }  

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

  1. public class JavaMemory{  
  2.     private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);  
  3.     public void f(){  
  4.         {  
  5.             byte[] data1 = new byte[dataSize];  
  6.         }  
  7.     int i=1;  
  8.         byte[] data2 = new byte[dataSize];  
  9.     }  
  10.  
  11.     public static void main(String[] args) {  
  12.         JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();  
  13.         jmp.f();  
  14.     }  
分享到:
评论

相关推荐

    java语言程序设计.pdf 电子书

    - 内存垃圾回收机制自动管理内存,避免内存泄漏等问题。 - 无显式指针和内存分配交给操作系统处理,进一步增强了程序的安全性。 - 字节码检验器在解释之前验证字节码的安全性。 - **Applet:**早期Java的重要...

    java 面试题 总结

     GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...

    java 反编译工具

    1. **什么是Java字节码**:Java程序首先被编译成字节码,这是一种平台无关的中间语言,由JVM(Java虚拟机)执行。字节码使得Java具有“一次编写,到处运行”的特性。 2. **为什么要反编译**:原始的源代码并不总是...

    java反编译工具

    1. **Java字节码**:Java程序在编译后会变成字节码,这是一种中间语言,可以在任何支持Java虚拟机(JVM)的平台上运行,实现了“一次编写,到处运行”的理念。字节码并不直接对应源代码,因此无法直接阅读。 2. **...

    IPA转apk超级工具

    - 安全风险:安装未经官方渠道发布的应用可能会带来安全风险,如恶意代码、隐私泄露等问题,用户需谨慎对待。 6. **潜在挑战** - 兼容性:由于iOS和Android系统之间的差异,有些应用可能无法在Android上完美运行...

Global site tag (gtag.js) - Google Analytics