C vs Java:无尽的循环创建对象仅崩溃C

C++ vs Java: endless loop creating objects only crashes C++

本文关键字:创建对象 崩溃 循环 无尽 vs Java      更新时间:2023-10-16

这是我的一本书中的一个问题(没有答案),我已经在考虑几天了。答案简单地说C 代码最终会崩溃,因为它在每次迭代后都会创建垃圾记忆单元?

考虑以下Java和C 代码片段,这是基于GUI的两个版本的一部分,该应用程序收集用户偏好并使用它们来组装命令及其参数。方法/函数getUserCommandSpecification()返回一个代表命令代码及其参数的字符串。返回的字符串用于构建所需的命令,然后执行该命令。

假设以下内容:

(i)在命令对象的while循环中创建后(由CMD在Java案例中引用或CMD在C 情况下指向),引用/指针CMD不再被引用或使用。

(ii)该应用程序还定义了类命令及其方法/函数execute()。

a。下面详细列出的两个代码版本中的哪个最终将崩溃。
b。解释为什么一个程序版本崩溃而另一个版本没有崩溃。

Java代码

...
while (true) {
   String commandSpecification = getUserCommandSpecification();
   Command cmd = new Command(commandSpecification);
   cmd.execute();
}
...

C 代码

...
while (true) {
   string commandSpecification = getUserCommandSpecification();
   Command* cmd = new Command(commandSpecification);
   cmd -> execute();
}
...

是的,C 版本由于new Command(...)而没有delete。当然,它很容易被不同的编码以避免:

...
while (true) {
   string commandSpecification = getUserCommandSpecification();
   Command cmd(commandSpecification);
   cmd.execute();
}
...

...所以我不确定示例是否像他们想象的那样具有启发性。

C 代码正在创建一个永不删除的Command对象。在C 中,没有垃圾收集。必须在new创建的所有实例上致电delete

使用原始指针的风格不佳。正如已经指出的那样,这里是不必要的。如果实际需要指针,请使用std :: unique_ptr。

while (true) {
   string commandSpecification = getUserCommandSpecification();
   std::unique_ptr<Command> cmd(new Command(commandSpecification));
   cmd -> execute();
}

这里没有内存泄漏。

C 示例将由于内存泄漏而崩溃。

Command* cmd = new Command(commandSpecification);

连续调用,没有相应的delete

在C 中,没有垃圾收集(范围内的当地人除外)。因此,C 连续分配堆上的Command对象,而无需通过呼叫delete释放该内存。因此,C 程序最终将用尽内存。

在Java中,垃圾收集器将看到堆上的对象不再被引用并释放它们,从而避免了内存错误。

afaik,在C 中,您需要在Java中明确销毁您创建的对象(使用new关键字)(垃圾收集器)可达)为您照顾它。

在Java中,以这样的方式创建的对象会增加次要GC的频率,因此这些对象甚至可能不会将其进入堆中的旧一代区域(取决于execute的运行时间)。<<<<<<<<<<<<

Java的极端性能

尚未明确说过(在页面中搜索单词没有匹配),我觉得最好添加:C 代码具有公然的内存泄漏 bug在其中。

使用std::auto_ptr(Boost的boost::scoped_ptr或QT的QScopedPointer是替代智能指针):

while (true) {
   string commandSpecification = getUserCommandSpecification();
   std::auto_ptr<Command> cmd(new Command(commandSpecification));
   cmd->execute();
}

阅读有关Java中垃圾收集的信息。在Java中,您不需要手动删除对象,因为JVM会自动为您使用,但是在C 中,您需要删除您不需要的对象。另外,垃圾收集器是Java中的功率完整工具,如果您需要帮助,您可以在工作完成后将对象引用到Null。

Object x=new Object()
///
.
.
.
you did your works
x=null;