Search code examples
javaandroidpoolingsoft-references

Is ReferenceQueue suitable for object pooling?


I'd like to use Buffer pooling in my library and thought about using SoftReferences to achieve an implicit return of objects and pool size balancing.

So, by "suitable" I mean:

  1. Are they quite performant compared to explicit ArrayBlockingQueue, for example? (less than order of magnitude)
  2. Are they reliable enough across modern VMs (like Hotspot, Dalvik, and ART) to behave "softer" than WeakReferences?

For me, it's not "premature optimization", just an architectural choice which can lead to less hassle with returning objects to the pool but will negate any benefits of pooling if doesn't meet specified requirements.


Solution

  • There is no reason to think that SoftReference or WeakReference don't work for any Java (tm) platform or for Android. There is an Android bug report that talks about difference between Java (tm) and Android behavior: Android clears soft references more "eagerly" than Java (tm). However, the analysis states that the differences are:

    • by design, and
    • within the "semantic envelop" of the specification; i.e. the Java(tm) javadocs.

    However, what I don't understand is how you propose to use Reference objects to implement return of objects (to the pool). If the code that has been allocated a buffer drops its (strong) reference to the object, then the weak or soft reference will be cleared before the reference is enqueued. That means that the buffer will be GC'd before the buffer pool's ReferenceQueue gets to hear about it.

    On the other hand, if you are merely using the weak / soft reference so that the pool isn't a memory leak ... that's OK. SoftReference is the right choice.

    SoftReference is not useful for explicit pool sizing. Soft references only respond to memory pressure, and you have little control over that.

    Finally, References and reference queues incur appreciable GC overheads. While they are unbroken, the GC must mark them when it encounters them. When the GC breaks them, there is an appreciable overhead in enqueing them, and in processing the queued Reference.