垃圾收集与非垃圾回收的编程语言(Garbage collection vs. non garbage

2019-07-18 01:38发布

所以,如果我理解不错,垃圾收集会自动回收未使用的程序了对象。 像在Java垃圾收集器。

我听到像C不支持垃圾回收程序可以有内存泄漏,随后耗尽内存语言。

那么,什么是错误的是程序员做的像C不支持垃圾回收的语言吗? 我猜后他们不再使用未重新分配的对象。 但这些唯一的错误,我们可以因为缺乏一个垃圾收集的?

Answer 1:

  • 你需要的东西Dellocating

  • 不重新分配的东西,你不再需要(因为你没有跟踪分配/使用/释放以及)

  • 重新分配的已经存在的事物的新实例(追踪不正确的副作用)

  • 解除分配的东西你已经释放

  • 解除分配的东西,不存在(空指针)

有可能更多。 问题的关键是:内存管理是棘手的,并使用某种形式的跟踪机制和分配/释放抽象最好的处理。 因此,你不妨有内置到你的语言,因此它可以使好和您轻松。 手册内存管理是不是世界的尽头 - 这肯定是可行的 - 但这些天,除非你正在编写实时代码,硬件驱动程序,或者(或许,可能)的最新超优化的核心代码游戏,那么手工努力是不值得的,除非学术活动。



Answer 2:

IMO,垃圾回收的语言有互补的问题,那些在非垃圾收集语言。 对于每一个问题,有一个非GC-特征的错误和GC-特征的错误 - 非GC程序员的责任和GC程序员的责任。

GC程序员可以相信,他们已经解除了释放对象的责任,但对象保存内存以外的资源 - 这往往需要及时地被释放,使他们能够在其他地方获得的资源 - 如文件句柄,记录锁,互斥。 ..

凡非GC程序员必须悬空引用(而且往往一个是不是一个错误,因为一些标志或其他国家将不会标记它使用),一个GC程序员有内存泄漏。 因此,当非GC程序员负责确保空闲/删除被适当地调用,一个GC程序员负责确保无用的引用被置空或以其他方式布置的适当。

有一个在这里声称智能指针不处理垃圾的循环。 这不一定是真实的 - 有可以打破循环,这也确保及时处置垃圾内存的引用计数方案,并用至少一个Java实现(和可能仍然这样做),可以很容易地被实现为引用计数方案C ++中的智能指针方案。

参考并发收集周期计数系统

当然,这并不正常进行 - 部分原因是因为你可能也只是使用GC的语言,也有部分IMO,因为它会破坏重要公约在C ++中。 你看,大量的C ++代码 - 包括标准库 - 在很大程度上依赖于资源分配初始化(RAII)约定,并且依赖于可靠和及时的析构函数调用。 在与周期科佩斯任何GC,你根本不能有。 当破垃圾周期,你可以不知道第一要调用的析构函数没有任何依赖性问题 - 它可能甚至是不可能的,因为有可能是不仅仅是内存引用多个循环依赖。 该解决方案 - 用Java等,也不能保证终结将被调用。 垃圾收集只收集一个非常特殊垃圾的种类 - 记忆。 所有其他资源必须手动清理,因为他们一直在Pascal和C,而没有可靠的C ++的优势 - 风格析构函数。

最终的结果 - 很多清理工作是获取C“自动化” ++,必须用Java手工完成,C#等。当然“自动化”,需要加引号,因为程序员负责确保删除适当要求的任何堆分配对象 - 但随后在GC语言,有不同但互补的程序员的责任。 无论哪种方式,如果程序员未能正确处理这些责任,你会得到错误。

[ 编辑 -有情况下的Java,C#等显然不可靠的(如果没有一定及时)清理和文件都是这样的例子。 这些都是对象,其中参考周期不可能发生 - 因为:(1)不包含在所有的引用,(2)有一些静态的证据证明它包含引用不能直接或间接导致回同一类型的另一个对象,或(3)在运行时逻辑可确保在链/树木/不管是可能的周期都没有。 例(1)和(2)是极为常见的用于资源管理的对象,而不是数据结构中的节点 - 也许普遍。 编译器本身不能保证合理(3),虽然。 因此,尽管标准库的开发,谁写的最重要的资源类,能保证可靠的清理这些,一般的规则还是非内存资源可靠的清理,不能保证一个GC,这可能会影响应用程序定义的资源。 ]

坦率地说,从非GC切换到GC(或反之亦然)是没有魔杖。 它可以使常规疑似问题消失,但这只是意味着你需要新的技能,以防止(和调试)的一组全新的嫌疑。

一个好的程序员应该让过去的卫生组织,侧面是 - 你 - 在BS,学会处理两种。



Answer 3:

那么,你可以使错误是:

  • 不重新分配的东西你不需要
  • 重新分配事情你需要

有可以使其他错误,但这些都是具体涉及垃圾回收的人。



Answer 4:

除了柔滑说的话你也可以增加一倍DEALLOCATE东西。



Answer 5:

除了其他意见,手动内存管理,使某些高性能并发算法更加困难。



Answer 6:

一些非GC语言提供结构称为引用计数智能指针。 这些尝试让周围的一些问题,例如忘记释放内存,或试图通过一些自动化的管理功能来访问无效的内存。

正如一些人所说,你必须是“智能”关于“智能指针”。 智能指针有助于避免一整类的问题,而是介绍自己的一类问题。

许多智能指针可以通过创建内存泄漏:

  • 周期或循环引用(A点到B,B点A)。
  • 在智能指针执行漏洞(成熟的库,例如升压少见)
  • 混合智能指针原始指针
  • 线程安全
  • 不适当地安装或从原始指针拆卸

这些问题不应该在充分GC'ed环境中遇到的。



Answer 7:

在C语言中,你必须手动调用free与分配的内存malloc 。 虽然这听起来并不坏,它可以用不同的数据结构处理(如链表),其指向同一数据时变得非常混乱。 你可能最终会访问释放的内存或双释放内存,这两者导致了错误,并且可能引起的安全漏洞。

此外,在C ++中,你需要小心混合new[]/deletenew/delete[]

例如,内存管理的东西,需要程序员确切地知道为什么

const char *getstr() { return "Hello, world!" }

只是罚款,但

const char *getstr() {
    char x[BUF_SIZE];
    fgets(x, BUF_SIZE, stdin);
    return x;
}

是一个非常糟糕的事情。



Answer 8:

另一个常见的错误是读或已释放它(这已经被重新分配,目前正用于别的东西,或存储它尚未realoocated,因此目前还在自己这是由堆管理器内存后写入内存而不是由您的应用程序)。



Answer 9:

通常情况下 ,垃圾收集语言限制程序员的内存访问,并依赖于一个存储模型,其中对象包括:

  • 引用计数器 - 气相色谱使用该知道什么时候一个对象是从未使用过,
  • 类型和尺寸的信息 - 消除缓冲区溢出(并帮助减少其他错误。

在具有非GC语言相比,有两类错误被减少/由模型和限制访问消除:

  1. 内存模型的错误,如:

    • 内存泄漏(完成后故障解除分配),
    • 释放内存不止一次,
    • 释放,这不是分配的内存(如全球或堆栈变量)
  2. 指针错误,如:

    • 未初始化的指针,与以前使用的“遗留”位,
    • 访问,释放后,尤其是写入,内存( 讨厌!)
    • 缓冲区溢出错误,
    • 使用的内存错误的类型(强制)。

还有更多,但这些都是大的。



Answer 10:

请谈垃圾收集时不比较OO语言(Java,C#)与非面向对象语言(C)。 面向对象的语言(大部分),可以实现GC(有关智能指针的评论)。 是的,他们是不容易的,但他们有很大的帮助,他们是确定性的。

此外,如何做考虑资源时内存以外,如GC-语言比较非GC-语言。 文件,网络连接,数据库连接,等等。

我想回答这个问题,留给读者,将阐明一些事情的光了。



文章来源: Garbage collection vs. non garbage collection programming languages