1

您可以创建新对象,但是当您使用完它们后,就没有真正的方法可以立即销毁它们吗?

为什么不是每个 OOP 运行时都实现这样的行为?

我敢肯定,作为开发人员,我们可以(经常)组织对象实例,以便在我们使用完对象实例后将其销毁。

function work(){
    var p1:Point = new Point(x, y);
    var p2:Point = new Point(x2, y2);

    ....

    destroy p1;
    destroy p2;
}
4

7 回答 7

9

从 .NET 来说,答案是内存安全。

考虑两个项目 A 和 B(对象或方法)都持有对对象 X 的引用。
现在 A 做了一个destroy X;. 然后 B 留下一个无效的引用。这是非托管语言中的常见错误模式。删除手动销毁可以防止这种情况。

但同样重要的问题是:它会有多大帮助?答案是不。.NET 中的短期内存非常便宜。您建议的销毁将没有任何价值。

于 2010-09-18T18:57:11.033 回答
5

简而言之,因为这通常会使编程任务复杂化。手动内存管理需要相当多的技能和努力才能做到正确 - 您不能将努力用于您要解决的实际任务。

您在上面展示的场景很常见,但远非唯一。如果您返回对其中一个对象的引用怎么办?如果你传递一个对被调用方法的引用(它可能被存储在哪里)怎么办?等等。这些都是您在负责任地销毁对象之前需要考虑的所有问题。这些统称为“所有权”。

硬币的另一面是,在执行期间能够在指定点销毁对象真的会产生积极影响吗?这使得析构函数和 C++ 中的 RAII 成为可能,这是一个非常强大的习语。Java没有,刚开始用Java的时候经常错过。但是,在 Java 中也有一些方法可以有效地解决这些问题(例如finally块)。无论 RAII 多么优雅,它仍然无法弥补手动内存管理可能导致的整个混乱。

然后你可能会建议,“为什么我们不能两者兼得:在我想要的时候显式销毁对象,而其余的则进行垃圾回收?”。而且您可以在编译器编写者和 JVM 实现者找到您之前开始寻找掩护 :-) 这会使事情变得非常复杂,如果没有真正巨大的、切实的好处,没有人会这样做。手动内存管理没有提供这样的东西。

于 2010-09-18T18:58:19.873 回答
2

不就是不。Java/C# 比 C++ 为您提供的最好的东西之一是内存管理 - 如果您必须自己处理它,那么它更容易出错,并且如果人们有可能使用和滥用它,从而产生越来越多的错误和内存泄漏要么是忘记释放某些东西,要么是做得太早。如果不考虑内存管理,设计/编码大型项目就已经够难了。

于 2010-09-18T19:00:59.070 回答
2

并非所有 OO 语言都具有垃圾收集 (Java) 或显式内存释放 (C++) 的原因是每种语言设计中选择的策略的结果。Java 不允许程序员显式地分配和释放内存。相反,程序员在处理引用变量时会处理它们

Point p = new Point(x,y);//p is a reference variable

并且 p 的释放是通过垃圾收集(自动)完成的。为了进行垃圾收集,您选择显式符号引用而不使用指针。因此,C++ 没有垃圾收集,也不能作为语言的固有特性提供。程序员必须使用显式释放内存

delete p;

或者编写自己的垃圾收集实现。因此,根据 OO 语言的设计,您要么进行垃圾收集,要么进行手动释放。你不能两者兼得。

于 2010-09-18T19:46:46.110 回答
1

C++ 是一种面向对象语言;它提供了可用于构造对象的“new”关键字和可用于销毁对象的“delete”关键字。如果不小心使用,删除对象可能会在 C++ 中产生灾难性的影响;如果单个对象有两个引用它的指针,并且您从一个指针中删除该对象,则另一个指针将变为无效,并且任何使用它的尝试都将是未定义的行为(通常程序将尝试使用内存位置中的值; 它可能已经被运行时重新分配用于其他目的)

于 2010-09-18T19:12:51.000 回答
1

对于 Java,请参阅Runtime.gc()

对于 C#,请参阅 System.GC.Collect

我不完全确定 C#,但在 Java 中,您只能请求进行垃圾收集,但是否实际清理未使用的引用的决定由虚拟机决定。

关于 C++ 风格的内存管理与解释语言中的垃圾收集是否性能更好,存在很多争论,但如果你在做 Java 或 C# 工作,我会怀疑你是否真的需要强制垃圾收集,一般来说,如果你来自 C++ 我建议抵制管理内存的诱惑,让 VM 优化为你做这件事。你应该确保你已经释放了对你不使用的对象的所有引用,以便它们可以被垃圾收集。我不会担心什么时候

于 2010-09-18T19:28:59.640 回答
1

您可以在大多数语言中将现有引用设置为 null 或类似的值,这将允许运行时根据需要对其进行垃圾收集。

我想你为方便系统管理你的记忆所付出的代价是你失去了很多自己想要的能力

于 2010-09-19T10:23:10.533 回答