我们喜爱Java的其中一个原因就是它的垃圾回收机制。绝大部分情况下,JVM都能过自动回收垃圾。
但是,在有些情形下,你还是要自己回收垃圾的,这些情形多是JVM无从通过“物理”性质来识别垃圾,而需要程序员通过“逻辑”性来判断哪些是垃圾并回收之。
所以,在支持垃圾回收的语言中,内存泄漏更应该被称之为“无意识的对象保持”。
例子:我们有两个String数组: a[100] 和 b[1000]。
现在要将a的所有元素拷贝给b(由于元素是String,所以写法和仅仅赋地址看起来是一样的),前提:不能改变b的地址,也就是不能new它(可能其它地方还保留着b的地址而且要用的着)
for (int i=0;i<a.lenght;i++){
b[i] = a[i];
}
完了吗?如果你认为工作完了,那么b[100]~b[999]就成了未被回收的垃圾,或称为未被释放的垃圾、无意被保留下来的垃圾。由于b整个数组的地址指针还在(没有改变地址),所以JVM是不会回收b中的任何一个元素的,JVM也不知道你的用意是用a来代替b,还是只更新b的前100个元素。
如果你的用意确实是前者的话,那么加上下面的代码吧:
for(int i=a.length; i<b.length; i++){
b[i] = null;
}
书上举的Stack的例子也是不错的,而且比起我这个例子来,Bug更不容易被意识到。再好好看一遍吧。
【Effective Java 学习笔记】系列连载专题请见:
http://tonylian.iteye.com/categories/64208