代码之家  ›  专栏  ›  技术社区  ›  Sundar R

为什么垃圾收集语言中不允许free()?

  •  16
  • Sundar R  · 技术社区  · 16 年前

    C# 在维基百科上,发现:

    为什么在具有自动内存管理的语言中,甚至没有手动管理 ? 我可以看到,在大多数情况下,这是没有必要的,但它会派上用场的地方,你是紧张的内存,不想依靠GC是聪明的?

    11 回复  |  直到 16 年前
        1
  •  5
  •   MSN    16 年前

    垃圾回收通过保证内存分配从不使用别名来强制内存分配器的类型安全。也就是说,如果一段内存当前被视为一个类型 T ,内存分配器可以保证(通过垃圾回收)当引用处于活动状态时,它将始终引用 T . 更具体地说,这意味着内存分配器永远不会以不同的类型返回该内存。

    现在,如果内存分配器允许手动 free() 并且使用垃圾回收,它必须保证你的内存 免费() ‘d’未被任何其他人引用;换句话说,你传递给 是那个记忆的唯一参照物。大多数情况下,这是令人望而却步的昂贵做一个任意调用 免费() ,所以大多数使用垃圾回收的内存分配器都不允许垃圾回收。

    这并不是说这是不可能的;如果可以表示单个引用类型,则可以手动管理它。但是在那一点上,停止使用GC语言或者干脆不用担心它会更容易。

        2
  •  10
  •   Phil Miller    16 年前

    具有自动内存管理的语言旨在提供实质性的内存安全保证,这是任何手动内存管理所不能提供的。

    • 双倍 free() s
    • 打电话 免费() 在指向您不拥有的内存的指针上,导致在其他位置非法访问
    • 免费() 在不是分配函数返回值的指针上,例如获取堆栈上或数组或其他分配中间的某个对象的地址。
    • 免费() d

        3
  •  1
  •   Doc Brown    16 年前

    打电话 GC.Collect free 方法。打电话 自由的 只对不知从何处引用的指针/对象引用有意义。这是一个容易出错的问题,因为您的呼叫 自由的

    当运行时环境引用 计数 GC 其中显式调用 对于单个内存块来说,可能比运行一个完整的 GC.收集 (但不要期望“手动”释放所有可能的内存块比GC快)。但是我认为C#、CLI(以及其他带有垃圾收集器的语言,比如Java)的设计者们已经决定在这里支持健壮性和安全性而不是速度。

        4
  •  1
  •   supercat    15 年前

        5
  •  0
  •   Pretzel    16 年前

    有趣的是,您确实可以通过System.GC访问垃圾收集器——尽管从我阅读的所有内容来看,强烈建议您允许GC管理自己。

    // Force garbage collection (cleanup event objects from previous run.)
    GC.Collect();         // Force an immediate garbage collection of all generations
    GC.GetTotalMemory(true);
    

    也就是说,除非我知道引擎盖下到底发生了什么,否则我不会为System.GC操心。在本例中,第三方供应商的建议“修复”了我正在处理的关于他们代码的问题。但我不禁要问,这是否真的是一个解决办法,为他们的坏代码。。。

        6
  •  0
  •   Andrey    16 年前

    如果您处于“不想依赖GC是聪明的”的情况,那么很可能您为您的任务错误地选择了框架。在.net中,您可以稍微操纵GC( http://msdn.microsoft.com/library/system.gc.aspx

    我认为你不能免费打电话,因为你开始做GC的一项任务。GC的效率可以在某种程度上得到总体保证,当它以它认为最好的方式做事时,当它决定的时候,它就会这样做。如果开发人员干扰GC,可能会降低它的整体效率。

        7
  •  0
  •   Evan Teran    16 年前

    这个 答案是,但我想到的是,如果你能 free ,你可以不小心加倍 自由的

    当然,一个可能的解决办法是 自由的 引用它的参数并将其设置为 null 释放后。但是,如果他们通过了考试呢 r-value 这样地: free(whatever()) . 我想你可能有一个r值版本的重载,但甚至不知道c是否支持这样的东西:-P。

    无效的 不会阻止其他人访问现在已解除分配的对象。

        8
  •  0
  •   svenningsson ahmed mohamady    16 年前

    许多其他答案很好地解释了GC是如何工作的,以及在针对提供GC的运行时系统编程时应该如何思考。

    我想添加一个技巧,我试图记住在GC'd语言编程时。规则是“尽快删除指针很重要”,删除指针意味着我不再指向我不再使用的对象。例如,在某些语言中,可以通过将变量设置为Null来实现这一点。这可以看作是对垃圾收集器的一个提示,即只要没有其他指向该对象的指针,就可以收集该对象。

        9
  •  0
  •   David Thornley    15 年前

    你为什么要使用 free() ? 假设您有一大块要释放的内存。

    一种方法是调用垃圾收集器,或者让它在系统需要时运行。在这种情况下,如果无法访问大块内存,它将被释放(现代垃圾收集器非常聪明。)这意味着,如果不释放它,它仍然可以被访问。

    因此,如果你能摆脱它与 免费()

    语言可以防止双重释放或试图释放未分配的内存,但避免悬空指针的唯一方法是取消指针 ,或修改其含义使其不再有用。

        10
  •  0
  •   J D    13 年前

    在绝大多数垃圾收集语言和vm中,提供 free

    原因主要有两个 自由的 在垃圾收集语言中不存在:

    1. 没有指针。

    自由的 使用同一个指针两次或使用不正确的指针可能会损坏内存管理器自己的数据结构,并在以后的程序中导致不确定的崩溃(当内存管理器下次访问其损坏的数据时)。自动内存管理不能做到这一点,但要公开 自由的 会再次打开这罐虫子。

    关于指针 函数在由指向内存管理器的指针指定的位置释放分配的内存块。垃圾收集语言和vm用一个更抽象的概念(称为引用)替换指针。大多数生产gc是移动的,这意味着高级代码持有对值或对象的引用,但内存中的底层位置可能会发生变化,因为VM能够在高级语言不知道的情况下移动分配的内存块。这用于压缩堆,防止碎片和改进局部性。

    所以我们有充分的理由不这样做 自由的 当你有GC的时候。

        11
  •  -1
  •   Evgeny Shadchnev    16 年前

    GC.start 会释放一切可以释放的东西,尽管你不能单独释放东西。