4

I have certain code that uses many instances of a SoftReference subclass. I would like test that it works correctly in cases when all / only some / none of these references are staged for clearing in ReferenceQueue. For the case of "none" this is quite easy: create strong references to the objects, and the soft references are guaranteed to stay. However, how would I go about guaranteeing them to be cleared? As I understand, System.gc() is only a request to run garbage collector, and even if it actually runs, it may well decide to not collect all unreachable objects...

Also the code is quite performance critical, so it's not a good idea to alter it just for testing purposes. (Adding a test-only method that doesn't affect other methods is fine, but adding paths that are used only for testing in other methods is something to avoid).

1 Answers1

1

If it is an option to access your SoftReference instances from the test you could simulate the GC behavior by calling methods directly on the SoftReference instances.

Calling SoftReference.clear() would correspond to the first step where the reference is cleared. Then you could call SoftReference.enqueue() to enqueue it in the reference queue, corresponding to the enqueing step the GC does [some time] after clearing the reference.

Calling these methods on a subset of your SoftReferences you could simulate that only some of the references have been cleared and enqueued.

I really think the above approach is to recommend since you got control of which references are cleared and that is a good thing in a test.

However, if you can not access your SoftReferences directly you are pretty much limited to allocating memory in an attempt to make the GC clear them. For example, as illustrated in this question and its answers.

Community
  • 1
  • 1
K Erlandsson
  • 13,408
  • 6
  • 51
  • 67
  • This sounds good, I didn't know you could enqueue references manually. As I said, it is not a problem to add test-only code to the class in question as long as "normal" code is not affected, and I guess adding something like `enqueueReferencesTo (Set > ...)` will do it. –  Jun 25 '15 at 19:49