会计考友 发表于 2012-8-4 12:37:27

JAVA基础:关于发现Java虚拟机内存泄露问题

内存泄露问题对于轨范来说,是一个很难发现,而且轻易引起严重灾难的工作。Java一向以其垃圾收受接管机制为孤高,那是否这种机制就是完美的呢。
  常规理解上,Java的内存打点机制是将局部变量保留在堆中,当变量的浸染域竣事之后,该变量所占用的内容会被自动收受接管。不需要做任何非凡的措置。好比下面的代码:
public class JavaMemory{
private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);
public void f(){
{
byte[] data1 = new byte;
}
byte[] data2 = new byte;
}
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;
data1 = null;
}
byte[] data2 = new byte;
}
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;
}
int i=1;
byte[] data2 = new byte;
}
public static void main(String[] args) {
JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();
jmp.f();
}
}
页: [1]
查看完整版本: JAVA基础:关于发现Java虚拟机内存泄露问题