发现Java虚拟机内存泄露问题
2010-06-01 15:20
344 查看
【IT168 文档
】内存
泄露问题对于程序来说,是一个很难发现,并且容易引起严重灾害的事情。
Java一直以其垃圾回收机制为自豪,那是否这种机制就是完美的呢。
常规理解上,Java的内存
管理机制是将局部变量保存在堆中,当变量的作用域结束之后,该变量所占用的
内容会被自动回收。不需要做任何特殊的处理。比如下面的代码:
#div_code img{border:0px;}
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。
这个问题该如何修正呢,方法其实很简单。只需要在变量作用域结束之前,将变量置为空就可以了。修改之后的结果如下:
#div_code img{border:0px;}
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开发者来说也许会很紧张,担心自己的代码是否会出现同样问题。大家尽可放
心,连续出现两个变量占用内存
之和超过内存
限制的情况概率非常小。并且在两个变量之间,如果定义了其他变量也不会出现
这个问题。如下面的代码就不会出现问题:
#div_code img{border:0px;}
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一直以其垃圾回收机制为自豪,那是否这种机制就是完美的呢。
常规理解上,Java的内存
管理机制是将局部变量保存在堆中,当变量的作用域结束之后,该变量所占用的
内容会被自动回收。不需要做任何特殊的处理。比如下面的代码:
#div_code img{border:0px;}
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。
这个问题该如何修正呢,方法其实很简单。只需要在变量作用域结束之前,将变量置为空就可以了。修改之后的结果如下:
#div_code img{border:0px;}
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开发者来说也许会很紧张,担心自己的代码是否会出现同样问题。大家尽可放
心,连续出现两个变量占用内存
之和超过内存
限制的情况概率非常小。并且在两个变量之间,如果定义了其他变量也不会出现
这个问题。如下面的代码就不会出现问题:
#div_code img{border:0px;}
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虚拟机内存泄露问题
- leakcanary作者发现的一个Dialog的各种listener容易引发的内存泄露问题
- 一次GTK程序内存泄露的解决过程发现的两个内存泄露的问题
- 从一个栈引出的内存泄露问题
- js内存泄露问题 .
- CStatic::SetBitmap导致的内存泄露问题
- 在web.xml中注册IntrospectorCleanupListener监听器以解决struts等框架可能产生的内存泄露问题
- c++ matlab混合编程时mxArray 内存泄露问题
- Android内存泄露检测工具和实际开发中遇到的内存泄露问题解析
- 关于WebView的内存泄露问题
- 应用 Valgrind 发现 Linux 程序的内存问题(转)
- 几个ajax js性能优化和内存泄露问题及检测分析工具
- Java有了GC同样会出现内存泄露问题
- 最近在SPARK上定位的几个内存泄露问题总结
- zookeeper_process内存泄露问题
- 应用 Valgrind 发现 Linux 程序的内存问题
- 使用按键精灵+umdh定位内存泄露问题的方式
- 内存泄露的小问题
- java程序会发生内存泄露的问题吗
- java程序会发生内存泄露的问题吗?请简单说说你的观点