【问题标题】:Dynamic Memory Handling Java vs C++动态内存处理 Java vs C++
【发布时间】:2010-10-29 18:56:13
【问题描述】:

我是一名 C++ 程序员,目前正在尝试使用 Java。在 C++ 上工作,我习惯于跟踪动态内存分配并采用各种技术(如 RAII)来避免内存泄漏。正如我们所知,Java 提供了一个垃圾收集器(GC)来处理内存泄漏。因此,在 Java 中编程时,应该放下堆内存的所有有害担忧,让 GC 处理内存泄漏还是应该一个有一种类似于在没有 GC 的情况下编程语言的方法,尝试处理您分配的内存,让 GC 处理您可能错过的内存。应该采取什么方法?两者的缺点是什么?

【问题讨论】:

  • 警告!检测到重大误解! 垃圾收集器不“处理内存泄漏”。 Java 容易受到其自身的内存泄漏子集的影响。垃圾收集器负责处理 未引用 对象。您仍然可以通过维护引用来泄漏内存。
  • @Mark:所以在 Java 中,因为没有删除(来自线程中的答案之一),所以应该更关心正在维护的引用,因为根本没有删除来清除任何堆?
  • 你绝对应该关心你的引用的生命周期(注意:这很少意味着你应该明确地将某些东西设置为空)。我不确定是否应该比 C++ 更关注 。无论哪种方式,维护对未使用对象的引用都是一个错误。在 Java 中,它表现为内存泄漏。在 C++ 中,如果你不删除它,这将是内存泄漏,如果你这样做,它可能会导致分段错误,或者如果你试图跟随指针指向一个已经被取消分配的东西,那么它可能会导致非常难以诊断错误。跨度>

标签: java c++ memory-management heap-memory


【解决方案1】:

我不确定你在 GC 的情况下尝试处理分配的内存是什么意思,但我会尝试一些读心术。

基本上,您不应该“担心”您的记忆被收集。如果您不再引用对象,它们将被拾取。如果您创建了一个为程序的其余部分引用对象的情况(例如:注册侦听器并且从不取消注册它们,例如:实现一个不将项目设置为 @987654321 的类向量集合),逻辑内存泄漏仍然可能@ 删除最后的项目时)。

但是,如果您具有强大的 RAII 背景,您会失望地得知 Java 中没有直接的等价物。 GC 是处理内存的一流工具,但不能保证何时(甚至是否)调用终结器。这意味着应用于内存的一级处理应用于任何其他资源,例如:窗口、数据库连接、套接字、文件、同步原语等。

【讨论】:

  • @Mark:我的印象是 Java 应该有类似 C++ 中的 delete 运算符,并且应该使用它来释放内存...刚刚通过线程发现..Java 没有删除。
  • +1 指出内存并不是唯一需要管理的资源
  • @FredOverflow:虽然我同意 GC 比没有 GC 好,但我仍然认为 GC 的整个概念有点像 hack,面向单一类型资源的管理。 .. 它恰好是 最常见的管理不善的资源!
【解决方案2】:

使用 Java 和 .net(我想,大多数其他经过 GC 处理的语言),您根本不需要担心堆内存。您要做需要担心的是本地资源,如文件句柄、套接字、GUI 原语(如字体等)。那些通常需要“处置”,这会释放原生资源。 (无论如何,他们经常在最终确定时自行处理,但要依靠它有点不确定。自己处理东西。)

【讨论】:

  • +1 指出内存并不是唯一需要管理的资源
【解决方案3】:

使用 GC,您必须:

  • 仍然注意正确释放非内存资源,如文件句柄和数据库连接。
  • 确保不再保留对不再需要的对象的引用(例如将它们保存在集合中)。因为如果这样做,就会发生内存泄漏。

除此之外,您不能真正“处理好您分配的内存”,尝试这样做会浪费时间。

【讨论】:

  • +1 指出内存并不是唯一需要管理的资源
【解决方案4】:

从技术上讲,您无需担心内存分配后的清理问题,因为所有对象都已正确引用计数,并且 GC 会处理所有事情。实际上,过度活跃的 GC 会对性能产生负面影响。因此,尽管 Java 没有 delete 运算符,但您最好尽可能重用对象。

Java 也没有析构函数,因为对象在 GC 到达它们之前一直存在。因此,Java 具有 finally 构造,您应该使用它来确保在完成所有非内存相关资源(文件套接字等)后关闭它们。不要依赖finalise 方法为您执行此操作。

【讨论】:

  • +1 指出内存并不是唯一需要管理的资源
【解决方案5】:

在 Java 中,GC 负责分配内存和释放未使用的内存。这并不意味着您可以完全忽视这个问题。

Java GC 释放没有从根目录引用的对象。这意味着如果你不小心从全局上下文中删除引用,如全局 HashMap 中的缓存等,Java 仍然可能存在内存泄漏。

如果没有从根目录引用任何相互引用的对象簇,Java GC 将释放它们。 IE。它不适用于引用计数,因此您不需要 null 所有对象引用(尽管某些编码样式确实更喜欢清除引用,因为它们不再需要了。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-16
    • 2012-01-01
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多