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

这项技术是否防止Java进行垃圾收集?

  •  3
  • stevendesu  · 技术社区  · 7 年前

    柯尔特·麦克安利斯做到了 a wonderfully entertaining video on preventing the JavaScript garbage collector from slowing down applications

    1. 当应用程序加载时,实例化一个未使用的对象/类池,这些对象/类是你的应用程序需要的 在将来的某个时候需要。
    2. 当您想实例化一个新对象时,应该在您的池中找到一个适当类型的未使用的对象,获取它并设置它的属性。
    3. 完成后,将其标记为“未使用”,以便将来的方法可以使用它。

    我的问题是,这种方法是否也适用于Java垃圾收集器,或者它是否更难绕过,最终只会扫描整个堆或其他东西。

    这主要是一个理论/好奇心的问题。我没有开发任何依赖于绕过垃圾收集的应用程序。

    1 回复  |  直到 7 年前
        1
  •  4
  •   Stephen C    7 年前

    从某种意义上说,它会“起作用”。但不建议这样做,因为存在一些重大问题。

    1. (如果您尝试使用 Reference 对象,最终会占用更多的空间,并在GC上放置更多的负载。)

    2. 当GC运行时,它必须遍历池中的所有对象,以及它们的所有依赖对象。这比让物体死亡要费劲(年轻的无法访问的对象根本不需要扫描。)

    3. 在几个GC周期之后,池中的对象将被保留,因为它们的寿命很长。这意味着它们将倾向于导致在旧堆被收集之前,可能会被收集的短期依赖对象被保留。此外,对终身对象字段的引用指定可能更昂贵,并且可能会使年轻的空间集合花费更长的时间(因为旧的->年轻的参考资料)。

    请注意,您所讨论的对象池类型通常是为了缓解应用程序中过多的GC暂停而提出/完成的。在一个典型的现代JVM中,gc是专门为最小化暂停而设计的。低暂停采集器是解决此问题的一个更好的选择 Java应用程序(一个例外是高度互动的游戏,任何形式的“滞后”都是不可接受的。)

    使用对象池还有其他原因:

    • 处理初始化成本很高的对象。
    • 处理数量有限的物体。

    示例包括线程池、数据库连接池和HTTP连接池(在典型的HTTP客户端库中隐藏)。在适当的情况下,这些绝对是有益的。