Java 中的对象池是什么?
什么是对象池以及什么是弱对象引用?
我们如何使用 Java 来实现它们?
What is object pooling and what is a weak object reference ?
How can we implement them using Java?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
对象池是应用程序将创建并保留在创建每个实例成本高昂的情况下的特定对象的集合。一个很好的例子是数据库连接或工作线程。该池为用户签入和签出实例,就像从图书馆借书一样。
通常对象池由 Java EE 应用服务器处理。如果您需要自己做,最好使用 Apache 的对象池之类的东西。不要自己写一个;线程安全和其他问题会使事情变得复杂。
这里关于弱对象引用的一个很好的参考。
An object pool is a collection of a particular object that an application will create and keep on hand for those situations where creating each instance is expensive. A good example would be a database connection or a worker thread. The pool checks instances in and out for users like books out of a library.
Usually object pooling is handled by a Java EE application server. If you need to do it yourself, best to use something like Apache's object pool. Don't write one yourself; thread safety and other issues can make it complicated.
Here's a good reference on weak object references.
检查 common-pools
,一般用于创建成本较高的对象。为了避免您维护一个包含 N 个预先创建的对象的池并重用它们。
Check common-pools
It is generally used for objects whose creation is expensive. In order to avoid that you maintain a pool of N pre-created objects and reuse them.
弱引用是垃圾收集器专门处理的一种引用变量。
这引入了另一种可达性,任何对象都可能是:
(还有软引用和幻像引用,我在这里省略了 - 它们的工作原理类似并引入了更多级别之间。)
如果一个对象根本不可访问,它可以随时被垃圾收集。
如果一个对象是强可达的,则它根本不能被垃圾回收。
如果垃圾收集器发现一个对象(或一组对象)是弱可访问的(可能是多个弱引用),它会立即清除所有这些引用,然后这些对象就不可访问了(并且可以被垃圾收集)。
(实际上,“不可访问”和集合之间存在/可能存在最终确定步骤,这也可能使对象再次可访问。)
对于使用弱引用,您可以使用类
java.lang.ref.WeakReference
- 实际引用位于此类的私有变量中,只能使用构造函数设置,然后清除。如果除了引用本身之外还需要其他数据(清除引用时这些数据应该仍然存在),则可以对此类进行子类化。对于“避免昂贵的实例化”意义上的对象池,弱引用不是正确的工具。
A weak reference is a kind of reference variable which is treated specially by the garbage collector.
This introduces another kind of reachability, any object may be:
(There are also Soft References and Phantom References, which I leave out here - they work similarly and introduce more levels between.)
If an object is not reachable at all, it can be garbage-collected at any time.
If an object is strongly reachable, it can not be garbage-collected at all.
If the garbage collector finds that an object (or a group of objects) is weakly reachable (maybe by multiple weak references), it clears all these references at once, and then the objects are not reachable (and can be garbage-collected).
(Actually there is/may be a finalization step between the "non reachable" and the collection, which also may make the object again reachable.)
For using Weak references, you can use the class
java.lang.ref.WeakReference
- the actual reference is in a private variable of this class, and can only be set with the constructor, and later cleared. You can subclass this class, if you need other data apart from the reference itself, which should still be there when the reference is cleared.For an object pool in the sense of "avoid costly instantiation", a weak reference is not the right tool.
对象池是回收对象的任何集合,而不是每次需要时重新创建。
根据您的要求,您可以通过多种方式实现此类对象池。对象池用于提高性能,即使对于简单的对象也是如此,但在 Java 5+ 中不再那么有用。
我建议您仅将它们用于连接到外部资源(例如文件、套接字或数据库连接)的对象。
An object pool is any collection of object which are recycled, rather than recreated each time they are needed.
There are a number of ways you can implement such an Object Pool depending on your requirements. Object pools used to help performance even for simple objects but are not as useful in Java 5+.
I suggest you only use them for objects which connection to external resources such as file, sockets or database connections.
池化和池化对象池:
池基本上意味着通过将对象的访问限制在客户端需要的时间段来有效地利用资源。
通过池化提高利用率通常会提高系统性能。
对象池是一种管理竞争客户端之间对有限对象集的访问的方法。
换句话说,对象池只不过是在不同客户端之间共享对象。
由于对象池允许共享对象,因此其他客户端/进程不需要重新实例化对象(这会减少加载时间),而是可以使用现有对象。
使用后,对象将返回到池中。
弱引用对象:
弱引用是对称为所指对象的对象的引用的持有者。
使用弱引用,您可以维护对引用对象的引用,而不会阻止它被垃圾收集。
当垃圾收集器跟踪堆时,如果对对象的唯一未完成引用是弱引用,则该引用对象将成为 GC 的候选者,就好像没有未完成的引用一样,并且所有未完成的弱引用都会被清除。
请记住,GC 总是使用一些算法来回收弱可达对象。
Pooling & Object Pooling:
Pooling basically means utilizing the resources efficiently, by limiting access of the objects to only the period the client requires it.
Increasing utilization through pooling usually increases system performance.
Object pooling is a way to manage access to a finite set of objects among competing clients.
In other words, object pooling is nothing but sharing of objects between different clients.
Since object pooling allows sharing of objects, the other clients/processes need not re-instantiate the object (which decreases the load time), instead they can use an existing object.
After the usage, the objects are returned to the pool.
Weak reference object:
A weak reference is a holder for a reference to an object called the referent.
With weak references, you can maintain a reference to the referent without preventing it from being garbage collected.
When the garbage collector traces the heap, if the only outstanding references to an object are weak references, the referent becomes a candidate for GC as if there were no outstanding references and any outstanding weak references are cleared.
Remember, GC always, using some algorithms, reclaim the weakly reachable objects.
对象池模式的思想与库类似。我们每个人都知道去图书馆借书比购买更便宜、更容易。同样,进程借用对象比实例化它更便宜(就系统内存和速度而言)。因此,一个进程从另一个进程借用对象的过程称为对象池。
The idea of object pool pattern is similar to that of library. Everyone of us know it is cheaper and easier to go to a library and borrow a book instead of buying it.Likewise, it is cheaper (with regards to system memory and speed) for a process to borrow an object rather then to instantiate it. So such process in which a process borrow an object from another process is termed as object pooling.
我实现了一个简单的 ObjectPool在 Java 中,请参见此处
但它不使用弱对象引用。弱对象引用的目的是允许收集对象内存,即使存在对该对象的引用,但它们是弱的。它对于缓存比对于对象池更有用,尽管也可以用于它们。
I implemented a simple ObjectPool in Java, see here
It doesn't use weak object reference though. Purpose of weak object reference to allow collect an object memory even if there are references to the object, but they are weak. It is more useful for caches than for object pools, although can be used for them too.
我怀疑您正在尝试询问 SoftReference 缓存(而不是 WeakReference)。我现在找不到它,但我记得读过一个实现专有 JVM 的人恳求人们不要使用它们。他的论点是,这些缓存假设垃圾收集器的作者以某种方式比您更了解您的缓存需求(这永远不应该是真的)。
我记得当时看到的是,如果 GC 周期没有释放足够的内存,所有软引用随后都会立即被清除,即缓存从可笑的(内存不足)满到(同样可笑的)完全空。相反,选择一种基于大小和/或年龄的缓存实现,即您可以为其提供自己的合理规则的缓存实现,而不是试图将缓存如何工作的决定权交给编写垃圾收集器的人由于某种原因。
I suspect you are trying to ask about a SoftReference cache (not WeakReference). I cannot find it right now, but I remember reading from someone who implemented a proprietary JVM begging people to not use them. His argument was that these caches suppose that the author of the garbage collector somehow knows more about your caching needs than you do (which should never be true).
What I recall seeing back in the day was that if a GC cycle did not free up enough memory, all SoftReferences subsequently got cleared at once, i.e. the cache goes from ridiculously (out of memory) full to (an equally ridiculous) totally empty. Instead, choose a cache implementation that works based on size, or age, or both, i.e. one that you can give your own sensible rules to, rather than trying to offload the decision of how your cache works to the person who wrote the garbage collector for some reason.