a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 102|回复: 0

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

[复制链接]
发表于 2012-8-4 12:37:27 | 显示全部楼层 |阅读模式
内存泄露问题对于轨范来说,是一个很难发现,而且轻易引起严重灾难的工作。Java一向以其垃圾收受接管机制为孤高,那是否这种机制就是完美的呢。
& D2 `3 I* S/ U2 g  常规理解上,Java的内存打点机制是将局部变量保留在堆中,当变量的浸染域竣事之后,该变量所占用的内容会被自动收受接管。不需要做任何非凡的措置。好比下面的代码:2 [# G, @, Z/ ?2 n
public class JavaMemory{! W" q( T2 {* ~' Y: n) Z1 z) k
private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6); 3 x! \. s+ D, \2 t' e
public void f(){, ?' i$ L6 X8 Z8 V# p. b
{, }3 g, G. O. G- N7 i5 S
byte[] data1 = new byte[dataSize];
$ |% U. i+ ^4 p0 I* I' Y$ e}# F3 p. n. ^; v1 K" S& {+ |
byte[] data2 = new byte[dataSize];3 y$ R! Z0 h+ y
}
2 j1 X6 O: `8 }! @) t* ppublic static void main(String[] args) {
4 p" |+ Z8 B9 _- e  ^JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();
$ |" @  H5 g. i+ W( i4 W6 u, Rjmp.f();8 f5 y9 Y9 k' J0 D: D: j
}* ?% p* Q7 S' r4 }& w
}
3 w; I6 q. y3 t" y3 O5 V8 A$ p/ q4 V5 [  在这个例子中,体例f()里界说了两个局部变量,变量data1和data2的浸染域分歧。按照正常理解,虽然两各个数组所需要的内存之和已经跨越了可用内存,可是因为data1会被实时收受接管,不会呈现内存溢犯错误。+ o% E: s5 k2 A3 Q
  如不美观我们现实执行这个例子,会发现呈现了java.lang.OutOfMemoryError错误。这是为什么?如不美观在BEA或者IBM的虚拟机上测试过这个例子,并不会呈现错误。也就是说,SUN的JVM在内存收受接管机制上存在裂痕或者BUG。
  ]2 j$ W1 r! h& u% Q% q  这个问题该若何批改呢,体例其实很简单。只需要在变量浸染域竣事之前,将变量置为空就可以了。改削之后的结不美观如下:
. P  Y: D4 L5 o  r: n: Upublic class JavaMemory{9 B6 ^! N' R/ y/ a' x5 [& M
private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);
0 u0 J/ N, }. ipublic void f(){; c, ?' o6 V1 h! D
{9 `/ j# h  {( S
byte[] data1 = new byte[dataSize];' d1 j5 r8 I$ K2 a0 @, l9 t
data1 = null;
" n# a$ [/ [% [" H. g6 U}
  A3 p9 \6 t8 B# t0 K4 z7 Qbyte[] data2 = new byte[dataSize];
8 ^- f0 W+ T# v; X' k3 w( B4 V}
# \% e! w5 X4 d& S7 [public static void main(String[] args) {; u+ y+ }5 t' Q7 o  c. m2 D
JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();7 D7 M  G# g8 p: W7 Q: c
jmp.f();3 u$ {  \4 W, R, x* ~; u6 b
}8 q7 u6 B+ i) q
}
5 b6 D1 _) d9 J0 e3 V9 U  发现这个问题,对于Java开发者来说也许会很严重,担忧自己的代码是否会呈现同样问题。巨匠尽可安心,持续呈现两个变量占用内存之和跨越内存限制的情形概率很是小。而且在两个变量之间,如不美观界说了其他变量也不会呈现这个问题。如下面的代码就不会呈现问题:
! p# a1 N7 `; ?+ V7 L; I# ~/ Bpublic class JavaMemory{! P  B4 N$ C8 M6 {/ n
private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);
* `% z9 S' H% w; z! c0 y7 Upublic void f(){
3 T( w1 P! [% ~+ b+ r7 _{
# N" d$ z8 }* B+ rbyte[] data1 = new byte[dataSize];
9 s7 P& Q' }# y/ [( H}
6 x8 X5 a+ G8 ]$ N4 K3 y( g  @int i=1;  S! d$ s& `: H4 }
byte[] data2 = new byte[dataSize];' i' g$ h/ ?) \# F
}! ]& _; c, _) v% I
public static void main(String[] args) {
2 ]; M4 j: R8 k; ~4 oJavaMemoryPuzzle jmp = new JavaMemoryPuzzle();2 C% f! n/ d9 @  p' b
jmp.f();8 ?5 H5 M7 [1 x2 e6 z2 D4 @
}9 ^  _. f: a1 d9 w
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-16 04:40 , Processed in 0.234890 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表