Login  Register

Re: imagej and Java 1.8

Posted by Aryeh Weiss on Dec 08, 2015; 5:29pm
URL: http://imagej.273.s1.nabble.com/imagej-and-Java-1-8-tp5015143p5015176.html

Hi Mark

Thanks again for your quick reply.
This reply is copied to the list because It may  be informative.

I have a minimal script that does something similar to what I reported.

from ij import IJ, Prefs, ImagePlus
from ij.io import DirectoryChooser,  OpenDialog
from ij.process import ImageConverter, ByteProcessor, BinaryProcessor

op = OpenDialog("Choose input image...", "")
path = op.getDirectory()+ op.getFileName()
inputName = op.getFileName()
inputDir = op.getDirectory()
inputPath = inputDir + inputName

if inputName[-4] == ".":
     inputPrefix = inputName[:-4]    # assumes that a suffix exists
else:
     inputPrefix = inputName


inputImp = ImagePlus(inputPath)
inputImp.show()
ImageConverter(inputImp).convertToGray8()

# The following line makes all the difference.
# inputIp = inputImp.getProcessor()

The line
inputIp = inputImp.getProcessor()

makes a reproducible difference. If it exists, then after running this
program, the image memory is not freed.
If I run this script multiple times, it seems to retain one copy (maybe
it overwrites the reference).

If I comment out this line, then gc will free all of the memory.
Moreover, if I ran it with this line uncommented, and the memory got
"stuck", and then I run it without
this lline (ie commented out), the next gc will free *all* of the memory.

I hope this is a useful clue.
--aryeh



On 08/12/2015 7:09 PM, Mark Hiner wrote:

> Thanks Aryeh!
>
> >How are hard references created?
>
> So first let me apologize for dragging you into the world of
> references. It is not a happy place and certainly not something a user
> or biologist should have to worry about, as it gets into the inner
> workings of Java itself.
>
> There's a nice succinct description of the different references here[1].
>
> Basically when an object is created it gets a "strong" by default, and
> you have to use special Java classes to get the other reference types.
> You get memory leaks when those strong references persist longer than
> expected (for example because they were created by something
> fundamental to the program).
>
> The way to fix the problem varies based on the actual cause - in your
> case it could be a bug in Jython itself.
>
> I'll look at your script and report back!
>
> Thanks again,
> Mark
>
> [1]
> https://www.rallydev.com/blog/engineering/java-references-strong-soft-weak-phantom
>
>
> On Tue, Dec 8, 2015 at 10:33 AM, Aryeh Weiss <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hi Mark
>
>     Thank you for this quick reply.
>     I am replying off-list so that I can attach the script.
>
>     On 08/12/2015 5:07 PM, Mark Hiner wrote:
>>     Hi Aryeh!
>>
>>     >I hope that this is useful.
>>
>>     Yep this is exactly what I needed and your thoroughness is
>>     greatly appreciated. :)
>>
>>     I started with heapdump-144955328636 and it was immediately clear
>>     that something on the python side is keeping hard references to
>>     your images. It looks like they are being stored in a
>>     ConcurrentHashMap which is not cleaned up when your script ends.
>>
>>     So it looks like a bug in the Python script you're using. I put
>>     up some screen captures[1] of the reference path that's keeping
>>     your objects alive, along with a brief interpretation. The
>>     variable names are distinct so I'm hoping it will be obvious
>>     where in your script they are being mapped. Ideally I would
>>     suggest caching weak references on the python side if that's an
>>     option, or possibly clearing the cache at the end of the script.
>>
>     I do not have any variable named snapshotPixels (or rLUT1, rLUT2,
>     etc), so I assume that these are variables internal to some plugin
>     that is used (or perhaps internal to IJ.
>
>     Some very basic questions:
>     How are hard references created?
>     Is there a way at the end of a script to tell it to clear all such
>     reference?
>
>>     If it's not clear how to fix the script and you'd like more eyes
>>     on it, share it here - happy to have a look! :)  Also happy to
>>     give more info on the heap dump analysis if anything's unclear there.
>>
>
>     I attached the script -- it is not well written (to say the very
>     least), as I am new at muddling my way through the API. The  most
>     recent addition to it is the mouse listener which I added to allow
>     the user to select three points near the end of the script.
>
>     Best regards
>     --aryeh
>
>>     If anyone else is interested in looking at the heap dumps I
>>     personally recommend the Eclipse Memory Analyzer plugin[2].
>>
>>     Best,
>>     Mark
>>
>>     [1] https://gist.github.com/hinerm/727453aab0837246367e
>>     [2] https://eclipse.org/mat/downloads.php
>>
>>     On Tue, Dec 8, 2015 at 2:25 AM, Aryeh Weiss <[hidden email]
>>     <mailto:[hidden email]>> wrote:
>>
>>
>>         Hi Mark
>>
>>         On 07/12/2015 11:04 PM, Mark Hiner wrote:
>>>         Hi Aryeh,
>>>
>>>         On Mon, Dec 7, 2015 at 11:46 AM, Aryeh Weiss
>>>         <[hidden email] <mailto:[hidden email]>> wrote:
>>>
>>>             Thanks for this information. I decided to run IJ, do a
>>>             heap dump before running a script that opens a few
>>>             1.3Gpixel images, then run it after, then close the
>>>             images and get a heap dump when the images have been
>>>             closed but the memory is not freed (which is reproducible).
>>>
>>>
>>>         This sounds like the perfect set of information!
>>>
>>>         > In order to send it to you, I will probably need to send
>>>         it to an FTP server (like I have done with bio-formats. DO
>>>         you have a server to which I can send the dumps?
>>>
>>>         Actually you should be able to use the Upload Sample
>>>         Image[1] command to send the zip. If that doesn't work for
>>>         you let me know and I can send FTP credentails.
>>>
>>
>>         I uploaded a set of heap dumps using  Upload Sample Image as
>>         you suggested.
>>         They are:
>>         heapdump-1449551945772 -- made immediately after launching
>>         Fiji. Small, as expected.
>>         heapdump-1449552198991 -- made immediately after running my
>>         python  script. Three large image are open.
>>         heapdump-1449552667004 -- made after closing those three
>>         large images and double clicking in the Fiji window
>>         a few times to run the garbage collector
>>         heapdump-1449553044705 -- made after running the script a
>>         second time, during which Fiji ran out of memory.
>>         Two large images are open.
>>         heapdump-1449553286368 -- made after closing those two
>>         windows and garbage collecting.
>>         As expected, memory was not freed.
>>
>>         The large images are a bit under 1Gpixel, 8-bit images.
>>
>>         I hope that this is useful.
>>         Thanks for your efforts.
>>         --aryeh
>>


--
Aryeh Weiss
Faculty of Engineering
Bar Ilan University
Ramat Gan 52900 Israel

Ph:  972-3-5317638
FAX: 972-3-7384051


--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html