代码之家  ›  专栏  ›  技术社区  ›  TraumaPony

垃圾收集可以与显式内存管理共存吗?

  •  8
  • TraumaPony  · 技术社区  · 16 年前

    例如,假设其中一个是在C#4中包含一个“delete”关键字。由于基于引用的系统,是否有可能保证您永远不会有通配符,但仍然能够依赖垃圾收集器?

    9 回复  |  直到 16 年前
        1
  •  3
  •   peterchen    16 年前

    在托管环境中,手动删除不太可能提高内存性能。它可能有助于处理非托管的资源,即dispose的全部内容。

    我宁愿让实现和使用一次性物品变得更容易。我没有一致、完整的想法,但在.NET下管理非托管的资源是一个冗长的难题。


    实施删除的想法: 删除标记要手动删除的对象。在下一个垃圾收集周期中,将删除该对象,并将对该对象的所有引用设置为null。

    这也不是特别安全的-例如,另一个线程可能正忙于执行该对象的成员方法,例如,在访问对象数据时,此类方法需要抛出。

        2
  •  2
  •   Mendelt    16 年前

    示例(伪代码):

    obj1 = new instance;
    obj2 = obj1;
    
    // 
    
    delete obj2;
    // obj1 now references the twilightzone.
    

    简而言之,将手动内存管理与垃圾收集相结合会破坏GC的目的。再说,何必麻烦呢?如果你真的想要控制,使用C++而不是C。

        3
  •  1
  •   Konrad Rudolph    16 年前

    你能得到的最好的方法是把一个半球分成两个半球,其中一个半球是被管理的,并且可以保证没有悬空的指针。另一个半球有明确的内存管理,不提供任何保证。这两者可以共存,但不,你不能给第二半球你的有力保证。你所能做的就是跟踪所有指针。如果其中一个被删除,那么指向同一实例的所有其他指针都可以设置为零。不用说,这是相当昂贵的。您的表会有所帮助,但会引入其他成本(双重间接)。

        5
  •  0
  •   Axeman maxelost    16 年前

    我的第一反应是:为什么不呢?我无法想象你想要做的事情会像在堆中留下一个未引用的块,以便以后再次找到它一样晦涩难懂。似乎一个指向堆的四字节指针太多,无法维护,无法跟踪该块。

    然而,问题在于:

    String s = "Here is a string."; 
    String t = s;
    String u = s;
    junk( s );
    

    你怎么办 t u 指向在严格的参考系统中, U null . 这意味着你不仅要做参考 计数

    然而,我可以看到你 应该 了结 s junk 可以将引用设置为null,并使用某种优先级代码将其传递给清扫器。gc可以被激活以进行有限的运行,并且只有在无法访问时才会释放内存。因此,我们不能明确地释放任何有人编写的代码,以某种方式再次使用。 如果 是唯一的引用,则该块被释放。

    所以,我认为它只适用于 有限的 明确的 一边

        6
  •  0
  •   Asik    15 年前

    这是可能的,并且已经实现,在非托管语言,如C++。基本上,您可以实现或使用现有的垃圾收集器:当您需要手动内存管理时,可以正常调用new和delete;当您需要垃圾收集器时,可以调用GC_MALLOC或垃圾收集器的任何函数或宏。

    看见 http://www.hpl.hp.com/personal/Hans_Boehm/gc/ 举个例子。

    因为您使用的是C#作为示例,所以您可能只想到用托管语言实现手动内存管理,但这是为了向您表明,反过来也是可能的。

        7
  •  0
  •   Thomas Eding    15 年前

    如果对象引用上的delete语义会使引用该对象的所有其他引用都为null,那么您可以使用两个间接级别(比您提示的多1个级别)来完成此操作。不过请注意,虽然底层对象将被销毁,但堆上必须保留固定数量的信息(足以保存引用)。

    GC的工作是清除这些隐藏的引用。

        8
  •  0
  •   user191535    14 年前

    这在使用长寿命对象的情况下会有所帮助。在短时间内使用对象并快速取消引用对象时,垃圾收集效果良好。问题是当某些对象存在很长时间时。清理它们的唯一方法是执行资源密集型垃圾收集。

    在这些情况下,如果有一种方法可以显式删除对象,或者至少有一种方法可以将对象图移回第0代,事情就会简单得多。

        9
  •  0
  •   Liran    5 年前

    如果你愿意和我一起玩 Marshal StructLayout 属性与 unsafe code

    您可以在此处找到该概念的演示: Writing a Manual Memory Manager in C# .