Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Toms answer is the correct one, however the code that has been added to the question is not the same as what was proposed by Tom. What Tom was proposing looks more like this:</p> <pre><code>class Bloat { // just a heap filler really public Reader res; private double a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z; private final int ii; public Bloat(final int ii, Reader res) { this.ii = ii; this.res = res; } } // as recommended by Tom Hawtin class MySoftBloatReference extends SoftReference&lt;Bloat&gt; { public final Reader hardRef; MySoftBloatReference(Bloat referent, ReferenceQueue&lt;Bloat&gt; q) { super(referent, q); this.hardRef = referent.res; } } //...meanwhile, somewhere in the neighbouring galaxy... { ReferenceQueue&lt;Bloat&gt; rq = new ReferenceQueue&lt;Bloat&gt;(); Set&lt;SoftReference&lt;Bloat&gt;&gt; set = new HashSet&lt;SoftReference&lt;Bloat&gt;&gt;(); int i=0; while(i&lt;50000) { set.add(new MySoftBloatReference(new Bloat(i, new StringReader("test")), rq)); MySoftBloatReference polled = (MySoftBloatReference) rq.poll(); if (polled != null) { // close the reference that we are holding on to try { polled.hardRef.close(); } catch (IOException e) { e.printStackTrace(); } } i++; } } </code></pre> <p>Note that the big difference is that the hard reference is to the object that needs to be closed. The surrounding object can, and will, be garbage collected, so you won't hit the OOM, however you still get a chance to close the reference. Once you leave the loop, that will also be garbage collected. Of course, in the real world, you probably wouldn't make <code>res</code> a public instance member.</p> <p>That said, if you are holding open file references, then you run a very real risk of running out of those before you run out of memory. You probably also want to have an LRU cache to ensure that you keep no more than <em>sticks finger in the air</em> 500 open files. These can also be of type MyReference so that they can also be garbage collected if need be.</p> <p>To clarify a little on how MySoftBloatReference works, the base class, that is SoftReference, still holds the reference to the object that is hogging all of the memory. This is the object that you need to be freed to prevent the OOM from happening. However, If the object is freed, you still need to free the resources that the Bloat is using, that is, Bloat is using two types of resource, memory and a file handle, both of these resources need to be freed, or you run out of one or the other of the resources. The SoftReference handles the pressure on the memory resource by freeing that object, however you also need to release the other resource, the file handle. Because Bloat has already been freed, we can't use it to free the related resource, so MySoftBloatReference keeps a hard reference to the internal resource that needs to be closed. Once it has been informed that the Bloat has been freed, i.e. once the reference turns up in the ReferenceQueue, then MySoftBloatReference can also close the related resource, through the hard reference that it has.</p> <p><b>EDIT:</b> Updated the code so that it compiles when thrown into a class. It uses a StringReader to illustrate the concept of how to close the Reader, which is being used to represent the external resource that needs to be freed. In this particular case closing that stream is effectively a no-op, and so is not needed, but it shows how to do so if it is needed.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload