问一个 Java 内存泄漏的问题

2015-10-19 10:47:01 +08:00
 RangerWolf
参考的文章: http://www.ibm.com/developerworks/cn/java/l-JavaMemoryLeak/

代码如下:
Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
Object o=new Object();
v.add(o); // 所有的 Object 对象都没有被释放,因为变量 v 引用这些对象
o=null;
}


我的问题就是,当运行这一段程序的 java 进程退出之后,内存泄漏还存在吗?
4026 次点击
所在节点    Java
27 条回复
RangerWolf
2015-10-20 10:18:09 +08:00
@CRVV 具体我不是非常了解,应该是属于 可达 无引用?
RangerWolf
2015-10-20 10:21:23 +08:00
@cnhongwei 您说的非常详细,学习到很多东西,非常感谢!
domty
2015-10-20 10:59:56 +08:00
@CRVV
java 是彻底的值传递,不存在引用传递的。
同理 java 里也没有传指针的概念。
Integer a = 10; //声明了一个 Integer 指向 Integer 型变量 10 。
Integer b = a; //声明了一个变量 b ,指向的地址和 a 指向的地址相同。
a = 20; //改变了 a 指向的地址, a 的指向为一个 20 的 Integer 型变量。这个时候 b 的指向还是 Integer 型 10 的地址。

这也是为什么 java 无法实现 swap(a,b)方法来交换两个变量的值得原因。
xiuc001
2015-10-20 11:04:19 +08:00
进程是操作系统创建的,进程没了,相应的堆栈信息都会被收回,而 java 程序是跑在这个进程中的,堆栈也是在进程的堆栈中,所以会被一起收回。。
简单的说 一起被收回~
CRVV
2015-10-20 11:23:42 +08:00
@domty
所以在你举的例子里,把所有的变量都当成指针,是不是完全符合 Java 的行为?
所以我前面用 C 的指针来类比 Java 的变量
关键是搞清楚语言的语义,至于有没有传指针的概念,我认为并不重要
wwqgtxx
2015-10-20 13:12:59 +08:00
@domty 对于对象是完全的引用传递,对于基础类型才是值传递,不要一概而论
sunnyhust2005
2015-10-20 15:05:26 +08:00
首先关于内存泄漏的概念需要澄清, Java 与 C/C++在这点上有很大的区别。从技术上来说, Java 不会出现 C/C++/Objective-C 所出现的内存泄漏。当在堆中分配的对象不再有指针指向时,就发生了内存泄漏;而对 Java 而言,不再有引用指向对象会被 GC 清除,所以不会有内存泄漏的问题。如果硬要认为 Java 也有内存泄漏,可以理解为“当对象的生命周期已经结束,但是有引用指向它,导致它无法被 GC 从堆中释放”。而后者和前者效果相同:都是内存中保留了不再需要的对象。

具体来看这个问题,在对局部变量 o 赋值为 null 前, Vector 对象在内部的数组里已经保存下来了 o 引用,所以不会发生 Java 意义上的内存泄漏。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/229122

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX