【发布时间】:2013-04-25 07:43:19
【问题描述】:
这是一个非常基本的问题。我将使用 C++ 和 Java 来制定它,但它确实与语言无关。 考虑 C++ 中的一个众所周知的问题:
struct Obj
{
boost::shared_ptr<Obj> m_field;
};
{
boost::shared_ptr<Obj> obj1(new Obj);
boost::shared_ptr<Obj> obj2(new Obj);
obj1->m_field = obj2;
obj2->m_field = obj1;
}
这是内存泄漏,每个人都知道 :)。解决方案也是众所周知的:应该使用弱指针来打破“引用计数互锁”。众所周知,这个问题原则上不能自动解决。解决它完全是程序员的责任。
但是有一件好事:程序员可以完全控制引用计数值。我可以在调试器中暂停我的程序并检查 obj1、obj2 的引用计数并了解存在问题。我还可以在对象的析构函数中设置断点并观察销毁时刻(或发现对象尚未被销毁)。
我的问题是关于 Java、C#、ActionScript 和其他“垃圾收集”语言。我可能会遗漏一些东西,但在我看来他们
- 不要让我检查对象的引用计数
- 当对象被销毁时不要让我知道(好的,当对象暴露给 GC 时)
我经常听到这些语言不允许程序员泄漏内存,这就是它们很棒的原因。据我了解,它们只是隐藏了内存管理问题并使其难以解决。
最后,问题本身:
Java:
public class Obj
{
public Obj m_field;
}
{
Obj obj1 = new Obj();
Obj obj2 = new Obj();
obj1.m_field = obj2;
obj2.m_field = obj1;
}
- 是内存泄漏吗?
- 如果是:如何检测和修复它?
- 如果不是:为什么?
【问题讨论】:
-
这不是内存泄漏。它不会保护您避免内存泄漏,但没有什么可以阻止您在析构函数中释放这些对象。内存管理是应用程序设计的一部分;低级技巧无法弥补设计上的不足。
-
不允许程序员泄漏内存不是这样的,但是这些语言可以在大多数情况下保护您免受内存泄漏。这对于那些没有的程序员来说是一个很大的优势任何关于内存的想法,我们至少在分配一些小项目时不需要太担心内存泄漏
-
无法访问引用计数,因为大多数实现不维护引用计数,并且语言通常注意不要限制比绝对必要更多的实现细节(因为这会阻止更好的实现——更快、更健壮,更有用等)。
标签: java c++ memory-management memory-leaks jvm