什么是Java中的对象池?

时间:2011-02-07 13:05:53

标签: java object-pooling

什么是对象池以及什么是弱对象引用?

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

8 个答案:

答案 0 :(得分:34)

对象池是应用程序将创建并保留的特定对象的集合,用于创建每个实例的代价高昂的情况。一个很好的例子是数据库连接或工作线程。该池会检查实例的进出情况,例如图书馆中的书籍。

通常,对象池由Java EE应用程序服务器处理。如果您需要自己动手,最好使用Apache的对象池。不要自己写一个;线程安全和其他问题可能使它变得复杂。

Here's对弱对象引用的一个很好的参考。

答案 1 :(得分:14)

检查common-pools

  

提供了一个Object-pooling API

它通常用于创建昂贵的对象。为了避免您维护N个预先创建的对象池并重用它们。

答案 2 :(得分:6)

弱引用是一种由垃圾收集器专门处理的引用变量。

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

  • 强烈可达(只能通过普通引用从任何生命线程到达)
  • 弱可达(不强可达,但可通过弱引用(或多种方式,每种方式包括弱引用)到达)。
  • 根本无法访问

(还有 Soft References Phantom References ,我在这里省略了它们 - 它们的工作方式类似,并介绍了更多级别。)

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

(实际上,“不可到达”和集合之间可能存在/可能是最终确定步骤,这也可能使对象再次可达。)

对于使用弱引用,您可以使用类java.lang.ref.WeakReference - 实际引用位于此类的私有变量中,并且只能使用构造函数进行设置,然后才能清除。如果你需要除引用本身之外的其他数据,你可以继承这个类,当引用被清除时,它仍然应该存在。

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

答案 3 :(得分:4)

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

根据您的要求,您可以通过多种方式实现此类对象池。对象池用于帮助简单对象的性能,但在Java 5+中不那么有用。

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

答案 4 :(得分:3)

对象池模式的概念类似于库的概念。我们每个人都知道更便宜,更容易去图书馆并借书而不是购买它。同样,对于借用对象而不是实例化它的过程来说,它更便宜(关于系统内存和速度)。因此,一个进程从另一个进程借用一个对象的进程被称为对象池。

答案 5 :(得分:2)

合并&对象池:

池化基本上意味着通过将对象的访问限制到客户端所需的时间来有效地利用资源。

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

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


弱引用对象:

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

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

我怀疑您正在尝试询问有关SoftReference缓存(不是WeakReference)的问题。我现在无法找到它,但我记得曾读过一个实现专有JVM的人,恳求人们不要使用它们。他的论据是,这些缓存假定垃圾收集器的作者比您更了解您的缓存需求(永远不应该如此)。

我回想起当初回想起的事情,如果GC周期没有释放足够的内存,那么所有SoftReferences随后都会被立即清除,即缓存从可笑的(内存不足)已满到(同样可笑)完全是空的。取而代之的是,选择一个基于大小或年龄或两者兼而有之的缓存实现,即可以给自己合理的规则的缓存实现,而不是尝试将缓存如何工作的决定转移给编写垃圾收集器的人由于某些原因。