0

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.

Pavlus
  • 1,651
  • 1
  • 13
  • 24
  • How do you actually plan on using soft references there? I think we can safely say that these constructs were not designed with any sort of pooling in mind - they are a finalization construct, and like any finalization of any sort you can't really expect it to be executed in any sort of reasonable timeframe or at all for that matter, as what happens depends on a huge number of JVM- and GC-specific configuration. – M. Prokhorov Mar 15 '17 at 11:15

1 Answers1

1

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • I meant that SR would be useful for implicit pool sizing -- if there is not enough memory -- they will be cleared. – Pavlus Mar 15 '17 at 16:18
  • For various reasons, relying solely on SRs for pools sizing could lead to performance problems. An explicit pool size would be better, possibly with SRs as well. However, the overheads are hard to measure because they would manifest as extra GC oherheads. – Stephen C Mar 15 '17 at 16:37
  • And by "return to the pool" I meant, that once there are no strong references to the object (it's not in use by third-party code anymore), it will be enqueued by GC, and since SoftReference still can, probably, be made strong, if not collected yet, we can use references from queue to reacquire those "intentionally lost" objects. And if there is no enough memory and plenty of unused objects -- they will be collected. – Pavlus Mar 15 '17 at 16:38
  • There can be some kind of hysteresis, with minimum pool size which can be refilled from ReferenceQueue on each acquire or by ones who explicitly return objects. – Pavlus Mar 15 '17 at 16:40
  • 2
    No. You are incorrect about the "return to pool". The package javadoc states *"Soft and weak references are automatically cleared by the collector before being added to the queues with which they are registered, if any."* – Stephen C Mar 15 '17 at 16:43
  • That was, actually, quite unexpected, because javadoc on ReferenceQueue says only about reachability changes. Thanks for notifying that. – Pavlus Mar 15 '17 at 17:05
  • Being within the semantic envelope could mean that there was no difference between Soft reference and WeakReference, since that would be the case if the GC never ran eagerly. – Pr0methean Oct 20 '17 at 07:35
  • I think that what they actually mean is the Android interpretation is that there is "memory pressure" whenever the GC has to run. That is within the semantic envelope of the javadoc, though probably not what the Sun engineers originally envisaged. Anyhow ... this is what Android does, and it is unlikely to change now. – Stephen C Oct 20 '17 at 07:50