7

这个问题是基于Java 中的 Thinking,第 2 版,第 109 页的Scope of Object章节,它说当我们使用new创建 Java 对象时,它会在范围结束时徘徊。它给出了这个例子:

{ 
  String s = new String("a string"); 
} /* end of scope */ 

然后它说,

引用 s在范围结束时消失。但是,s 指向的 String 对象仍在占用内存。在这段代码中,无法访问该对象,因为对它的唯一引用超出了范围。

因此,如果我理解正确,文本“a string”仍然存在于内存中,但具有第一个字符'a'的内存地址的指针不存在。这就是它的意思吗?

它接着说,

事实证明,因为用 new 创建的对象只要你想要它们就一直存在,一大堆 C++ 编程问题在 Java 中就消失了。

为什么这会是有利的?在上面的示例中,字符串数据继续驻留在内存中,无法访问它(因为指针在超出范围后被销毁),这只会消耗资源。

4

8 回答 8

3

简单来说,s段中引用变量的作用域:

{ 
  String s = new String("a string"); 
} /* end of scope */ 

在大括号之间。这意味着s只存在于开始和结束{}之间。然而,在那个区块中发生了一些事情。

在大括号内,new调用运算符来创建String对象的实例。为对象分配内存,并将对它的引用分配给变量s

在代码块的末尾,s不再存在,因此它所持有的引用不再存在。String但是,该对象仍然存在于内存中。但是由于不再有任何变量持有对它的引用,程序的任何部分都无法再访问它。此时,该对象符合垃圾回收条件。

在一个对象被垃圾回收之前,它仍然占据系统内存中的一个位置,即使它不再被程序访问。

于 2013-07-15T05:30:41.377 回答
2

翻到第 215 页,了解垃圾收集器的工作原理

当 Java 代码运行时,垃圾收集器会定期运行以查找所有未被引用的对象并释放它们占用的内存。发生这种情况时,将finalize在您的对象上调用该方法(如果已定义)。那时您执行对象所需的任何清理。

使用 c++,您必须担心自己使用delete关键字释放内存 - 不这样做可能会导致内存泄漏。

使用 Java,您可以将内存分配管理换成托管对象生命周期管理。

于 2013-07-15T05:29:57.457 回答
2

一旦Object退出,scope它将准备进行垃圾回收,直到 GC 收集到分离的对象,才会占用内存。

于 2013-07-15T05:19:32.343 回答
1

在 Java 中,一旦对对象的所有引用都被清空或超出范围,对象本身就会成为垃圾收集器销毁的候选对象。GC 根据自己的算法自动执行此操作,而在 C++ 中,您必须显式销毁对象。此外,由于所谓的实习,字符串可能会继续存在。

于 2013-07-15T05:24:22.410 回答
1

好吧,它驻留在内存中,直到 Java 垃圾收集器为您清理它。它会定期执行此操作。这意味着您不必自己管理内存。

您可以创建对象而不必担心分配和释放内存。

于 2013-07-15T05:19:08.223 回答
1

由于对象超出范围,java垃圾收集器会自动对它进行垃圾收集。它比 C++ 更有利,因为在 Java 中,Java 运行时会自动处理垃圾收集,因此最终会回收内存。这不是 C++ 的情况

于 2013-07-15T05:20:16.870 回答
1

当这本书谈到仍然占用内存的代码块时,我不明白这本书试图表达的观点。也许它想说的是,仅仅因为引用变量(如s示例中的)超出范围,并不意味着立即释放内存。它没有说明(至少在您发布的内容中)是这样的内存会受到自动垃圾收集的影响,事实上,您应该像这样的孤立内存块一样进行编程。

与 C++ 相比,Java 中的垃圾收集的优点在于它是自动完成的。当对内存分配的所有强引用(包括所有间接引用)超出范围时,该内存块将受到自动垃圾回收的影响。简而言之就是这样。Java 可以正确处理循环引用之类的事情,并将垃圾收集任意复杂的数据结构,前提是该结构不能直接或间接从仍在范围内的任何引用值访问。

此外,由于interning的原因,字符串有特殊的规则,所以这本书在那个例子中有点失败。

于 2013-07-15T05:20:57.503 回答
0

意思是对象没有“躺在”它仍然在内存中等待垃圾收集器收集。像这样想。你的房子里有很多物品,你想摆脱其中的一些并保留一些。您有一个垃圾收集器来您家处理不需要的物品,但是为了让他区分您想要保留的物品和您想要丢弃的物品,您标记了您希望他收集的物品他到了。这就是垃圾收集器的工作方式。首先,它标记所有不需要的对象,然后一次收集它们。垃圾收集器经常运行。

于 2018-10-14T17:56:55.913 回答