内存洩露问题对于程序来说
是一个很难发现
并且容易引起严重灾害的事情
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();
}
}