java 为什么会内存泄露,这个典型的例子为什么会造成内存泄露?

xooxoo 2010-04-15 07:05:49
http://www.cnblogs.com/dotnetdoor/archive/2008/06/09/1216125.html
看到一篇内存泄露的文章:
文章中举了一个内存泄露的例子:
Vector v = new Vector(10);
for (int i = 1; i<100; i++)
{Object o = new Object();
v.add(o);
o = null;
}//

文章中描述:
在这个例子中,循环申请Object 对象,并将所申请的对象放入一个Vector 中,如果仅仅释放引用本身,那么Vector 仍然引用该对象,所以这个对象对GC 来说是不可回收的。因此,如果对象加入到Vector 后,还必须从Vector 中删除,最简单的方法就是将Vector对象设置为null。

在我看来 vector中的 o 已经都统统指向了 null 而 new 出来的Object 已经没有对象再应引用它了,没用被应用的对象就应当被回收啊,所以这些new Object会被释放
请教各位,我的想法错在哪里?
...全文
10501 49 打赏 收藏 转发到动态 举报
写回复
用AI写文章
49 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
Life lies in movement, programing lies in thinking.
jnu_cc 2012-02-22
  • 打赏
  • 举报
回复
操,妈个B的,搞了我想半天,例子没贴全,注释也是代码的一部分!!整个例子的意思如下:
Vector v = new Vector(10);
for (int i = 1; i<100; i++)
{Object o = new Object();
v.add(o);
o = null;
}
//balababala........................这里使用v
//但是下面的程序不会再使用v了,这里如果不将v=null的话,就会一直占用堆空间。在另一个角度来说,貌似内存不见了一部分,“变小”了,如果有N个类似这样的v,就会导致内存溢出问题。

ysm0420 2011-08-12
  • 打赏
  • 举报
回复
既然V还引用object,那么这个object就还可以被用到,为什么说是内存泄漏?还是不懂~
zha_zi 2010-07-14
  • 打赏
  • 举报
回复
Vector v = new Vector(10);
for (int i = 1; i<100; i++)
{Object o = new Object();//o 是一个引用在这个是这这个应用存放的是刚刚new出来的object的地址
v.add(o);// 在v中添加了指向object的地址
o = nul…… //所以在这个时候改变o的引用是对v不起作用的,v中存放的并不是o的值,而是当时o的指向的object的引用地址

pywepe 2010-04-18
  • 打赏
  • 举报
回复
[Quote=引用楼主 xooxoo 的回复:]
http://www.cnblogs.com/dotnetdoor/archive/2008/06/09/1216125.html
看到一篇内存泄露的文章:
文章中举了一个内存泄露的例子:
Vector v = new Vector(10);
for (int i = 1; i<100; i++)
{Object o = new Object();
v.add(o);
o = nul……
[/Quote]

出了{} o就不存在了 设不设都没所谓
groovy2007 2010-04-18
  • 打赏
  • 举报
回复
这个例子跟内存泄露一点关系都没有
宅男小何 2010-04-17
  • 打赏
  • 举报
回复
不会哦,我以前这这样写代码,但是通过Vector,访问不到加入的对象了 啊?报NULLPointerException
tu0 2010-04-17
  • 打赏
  • 举报
回复
关键是栈和堆的概念 特别是java在处理 一楼说的很对 Object o = new Object() ;o是在栈一个单元,记录的是new object()在堆中开辟的内存地址,所以每当你使用v.add(o)实际上也就将地址copy一份记录下来,所以当o=null时只是将栈中记录地址的单元清空,而v还是有指向堆中的内存单元。GC只存在于堆中,所以在堆中开辟的内存单元在栈中还有一个记录它地址的引用,所以至少现在是不能被回收的。
  • 打赏
  • 举报
回复
呵呵,幸勤的小蚂蚁。

实际上就算显式地 = null 那也是无济于事的,这样做只是把变量指向了一个 null,但是原本的数据会被扔掉,同样需要 GC 进行清扫。

GC 一般情况下都是在那里打盹,一旦 JVM 内存开始紧张的时候,GC 才会开始工作,呵呵。
qjtttt 2010-04-17
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 bao110908 的回复:]
不需要把那个 Vector 置为 null,如果那个 Vector 是局部变量,那只要离开了局部变量的作用范围,那么这一块区域就是不可用的了,在垃圾回收器启动时会将其进行回收的。

因此,一般也建议编写代码时尽可能地缩小局部变量的作用范围。
[/Quote]

那是,生命周期到了就开始GC就开始工作了,辛勤的小蚂蚁,就是有时候容易打盹,线程的优先级还是太低了
sweetBug 2010-04-17
  • 打赏
  • 举报
回复
好像在哪里看到过,如果JAVA中引用了C代码用malloc申请的内存块,并且没有在引用的JAVA对象的finalize方法里写相应的代码来释放这个C代码申请的内存,JAVA的垃圾回收好像是回收不了的。
想起来了,是thinking in java里面的
jackmtlee 2010-04-17
  • 打赏
  • 举报
回复
首先要搞清楚什么样的对象会被JVM扫描后当作垃圾回收。当一个对象不被任何引用指向的时候(不知道这么说合理否),它才会被GC回收,而虽然o与new Object()切断了联系,但仍有v[index]指向new Object()。故不能被GCing。
anbyle 2010-04-17
  • 打赏
  • 举报
回复
学习一下~
龙四 2010-04-17
  • 打赏
  • 举报
回复
最简单的例子,打开文件没关闭,这个java管不了啊。。。
  • 打赏
  • 举报
回复
不需要把那个 Vector 置为 null,如果那个 Vector 是局部变量,那只要离开了局部变量的作用范围,那么这一块区域就是不可用的了,在垃圾回收器启动时会将其进行回收的。

因此,一般也建议编写代码时尽可能地缩小局部变量的作用范围。
qjtttt 2010-04-17
  • 打赏
  • 举报
回复
执行结果:
before "object=null" objcet===java.lang.Object@18a992f
after "object=null" object===null
vector.get(0)===java.lang.Object@18a992f

明显的没有执行object=null之前object和vector.get(0)指向的是同一个对象
而object=null;这里只能理解为把object这个引用和java.lang.Object@18a992f地址指向的数据的联系给断开了而已,并不是将java.lang.Object@18a992f指向的内存的数据都当做垃圾回收
xjlgy 2010-04-17
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 bao110908 的回复:]

这个不叫内存泄露,这是内存溢出,也就是说 JVM 已经没有可以掌控的内存空间分配给新产生的对象了。
[/Quote]

火龙果 大哥,个人觉得 这个是典型的 内存泄露 例子,因为这里只 new 了99个Object ,不存在 内存不够问题
ycbzzjl 2010-04-17
  • 打赏
  • 举报
回复
学习了!一楼说的很好。
qjtttt 2010-04-17
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 lazy_p 的回复:]
不会哦,我以前这这样写代码,但是通过Vector,访问不到加入的对象了 啊?报NULLPointerException
[/Quote]
不多争论,事实证明一切;

public static void main(String[] args) {
Vector vector=new Vector();
Object object=new Object();
vector.add(object);
System.out.println("before \"object=null\" objcet==="+object);
object=null;
System.out.println("after \"object=null\" object==="+object);
System.out.println("vector.get(0)==="+vector.get(0));
}
qqbz 2010-04-17
  • 打赏
  • 举报
回复
对于java,其实是不必象其他语言一样,关注变量以及对象的释放问题.因为有垃圾收集机制.能处理大部分情况.

通常而言,关于java这方面的问题是集中在垃圾收集机制什么时候起作用:java官方自己对于这方面的描述是:不知道什么时候会确实回收,即使是显式地调用了垃圾回收的代码.

java还是存在内存泄漏(不管怎么叫吧,就是内存没有被释放)的问题的,关于这方面的例子,记得应该在<java编程思想>上有示例代码,他是要说明的是在某些情况下,即使调用了垃圾回收代码,也不能确保这些内存被回收了.

不过无论怎么说,在实际中编写java程序无需考虑释放内存问题,很多实际代码都没有在最后赋null.
加载更多回复(28)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧