31

什么是对象池,什么是弱对象引用?

我们如何使用 Java 实现它们?

4

8 回答 8

37

对象池是应用程序将创建的特定对象的集合,并在创建每个实例的成本很高的情况下随时可用。一个很好的例子是数据库连接或工作线程。池为用户检查实例,例如图书馆的书籍。

通常对象池由 Java EE 应用服务器处理。如果你需要自己做,最好使用 Apache 的对象池之类的东西。不要自己写;线程安全和其他问题会使它变得复杂。

这是关于弱对象引用的一个很好的参考。

于 2011-02-07T13:10:25.003 回答
16

检查公共池

提供对象池 API

它通常用于创建成本高昂的对象。为了避免您维护一个由 N 个预先创建的对象组成的池并重用它们。

于 2011-02-07T13:10:00.687 回答
8

弱引用是一种被垃圾收集器特殊处理的引用变量。

这引入了另一种可达性,任何对象都可能是:

  • 强可达(仅通过普通引用从任何生命线可达)
  • 弱可达(不是强可达,但可以通过弱引用(或通过多种方式,每种方式都包含弱引用))
  • 根本无法到达

(还有Soft ReferencesPhantom References,我在这里省略了——它们的工作方式类似,并且在它们之间引入了更多级别。)

如果一个对象根本无法访问,它可以随时被垃圾回收。如果一个对象是强可达的,那么它根本不能被垃圾收集。如果垃圾收集器发现一个对象(或一组对象)是弱可达的(可能是多个弱引用),它会立即清除所有这些引用,然后这些对象是不可达的(并且可以被垃圾回收)。

(实际上在“不可到达”和集合之间有/可能有一个完成步骤,这也可能使对象再次可到达。)

对于使用弱引用,你可以使用类java.lang.ref.WeakReference——实际引用在这个类的一个私有变量中,只能用构造函数设置,然后清除。如果您需要除引用本身之外的其他数据(在清除引用时应该仍然存在),您可以对此类进行子类化。

对于“避免昂贵的实例化”意义上的对象池,弱引用不是正确的工具。

于 2011-02-07T13:33:20.940 回答
5

对象池是可回收的任何对象集合,而不是在每次需要时重新创建。

根据您的要求,您可以通过多种方式实现这样的对象池。对象池用于帮助提高性能,即使是简单的对象,但在 Java 5+ 中没有那么有用。

我建议你只将它们用于连接到外部资源的对象,例如文件、套接字或数据库连接。

于 2011-02-07T13:29:53.180 回答
4

对象池模式的思想类似于库的思想。我们每个人都知道去图书馆借书比买书更便宜、更容易。同样,进程借用对象而不是实例化对象更便宜(就系统内存和速度而言)。因此,一个进程从另一个进程借用对象的过程称为对象池。

于 2015-04-15T18:17:29.300 回答
4

池化和对象池化:

池化基本上意味着有效地利用资源,通过将对象的访问限制在客户端需要它的时间段内。

通过池提高利用率通常会提高系统性能。
对象池是一种管理竞争客户端之间对有限对象集的访问的方法。
换句话说,对象池只不过是在不同客户端之间共享对象。

由于对象池允许共享对象,其他客户端/进程不需要重新实例化对象(这减少了加载时间),而是可以使用现有对象。
使用后,对象将返回到池中。


弱引用对象:

弱引用是对称为所指对象的引用的持有者。
使用弱引用,您可以维护对所指对象的引用,而不会阻止它被垃圾收集。
当垃圾收集器跟踪堆时,如果对一个对象的唯一未完成的引用是弱引用,则该引用对象将成为 GC 的候选对象,就好像没有未完成的引用并且任何未完成的弱引用都被清除一样。

请记住,GC 总是使用一些算法来回收弱可达对象。

于 2011-02-07T13:30:08.073 回答
0

我在 Java 中实现了一个简单的ObjectPool,请参见这里虽然它不使用弱对象引用。弱对象引用的目的是允许收集对象内存,即使有对对象的引用,但它们是弱的。它对缓存比对对象池更有用,尽管也可以用于它们。

于 2014-06-18T23:24:59.827 回答
0

我怀疑您正在尝试询问 SoftReference 缓存(而不是 WeakReference)。我现在找不到它,但我记得读过一个实现专有 JVM 的人请求人们不要使用它们。他的论点是,这些缓存假设垃圾收集器的作者不知何故比您更了解您的缓存需求(这永远不应该是真的)。

我记得那天看到的是,如果一个 GC 循环没有释放足够的内存,所有的 SoftReferences 随后都会立即被清除,即缓存从可笑(内存不足)满到(同样可笑)完全空。取而代之的是,选择一个基于大小或年龄或两者都起作用的缓存实现,即您可以给自己的合理规则的缓存实现,而不是试图将缓存如何工作的决定交给编写垃圾收集器的人由于某些原因。

于 2019-10-15T00:57:48.947 回答