科特·麦卡利斯({@ 3}}
其要旨如下:
我的问题是,这种方法是否也可以与Java垃圾收集器一起使用,或者是否更棘手,并且最终只能扫描整个堆或其他内容。
这主要是理论/好奇心。我在开发中没有依赖于规避垃圾收集的应用程序。
答案 0 :(得分:4)
从某种意义上说,它将“起作用”。但不建议这样做,因为存在一些重大问题。
如果执行不正确,将导致内存泄漏。问题是“池”需要保留对其所有对象的引用。这样可以防止随后被垃圾回收。但是,如果应用程序在完成对对象的处理后始终无法将其标记为“未使用”(例如错误),则这些对象将永远保持“使用中”。
(如果您尝试使用Reference
对象之类的东西来减轻这种情况,则会最终占用更多空间,并给GC带来更多负担。)
GC确实运行时,它必须遍历池中的所有对象以及它们的所有从属对象。这比允许对象死亡的工作要多。 (根本不需要扫描年轻的无法到达的物体。)
经过几个GC周期后,您的池中的对象将被保留,因为它们的寿命很长。这意味着它们将趋向于导致短期依赖的对象,这些对象本来可以收集起来,直到收集旧堆为止。同样,对保有权对象字段的引用分配可能会更昂贵,并且可能会使年轻空间的收集花费更长的时间(由于旧的->年轻引用)。
请注意,通常会建议/完成您正在谈论的对象池类型,以减轻应用程序中过多的GC暂停。在典型的现代JVM中,有些GC专门设计用于最大程度地减少暂停。低暂停收集器是解决 most Java应用程序中此问题的更好选择。 (高度互动的游戏是例外,在这种游戏中,任何形式的“滞后”都是无法接受的。)
使用对象池还有其他原因:
示例包括线程池,数据库连接池和HTTP连接池(在典型的HTTP客户端库的后台)。在适当的情况下,这些绝对是有益的。