Memory issues with IJ2 to IJ1 conversion using LegacyService

imagej-legacy
memory
imagej2
imagej1
Tags: #<Tag:0x00007fb87d5c3338> #<Tag:0x00007fb87d5c31f8> #<Tag:0x00007fb87d5c3040> #<Tag:0x00007fb87d5c2f00>

#1

Hi

Ive been experimenting with “mixed world” IJ2 and IJ1 commands. Its working really well but Ive been having some memory build up issues which eventually lead to “Out of Memory” errors if the command is run on a large number of datasets. I think Ive narrowed the problem down to the conversion from IJ2 datasets to IJ1 ImagePlus objects. The following groovy script should hopefully reproduce this problem, its much more obvious if run on a largeish multidimensional dataset.

Any help or advice would be much appreciated.

Thank you

Jeremy


// @ImageJ ij
// @Dataset currentData

import net.imagej.legacy.LegacyService;
import ij.ImagePlus;
import ij.IJ;
import java.lang.System;


// create legacy service for conversion between IJ and IJ2 classes
LegacyService legacy = ij.get(LegacyService.class);


// run conversion a few times to demonstrate memory build up
for (int i = 0; i < 25; i++) {
	println(i);
	// convert to float, this makes the issue more obvious
	dataFloat = ij.op().run("convert.float32", currentData);

	// convert to IJ1 ImagePlus
	imp = legacy.getImageMap().registerDataset(dataFloat);

	 
}

// My attempt to clean up
dataFloat = null;
imp = null;
legacy = null;
System.gc();


#2

Hi Jeremy,

I can reproduce the issue that you are describing on my machine.

Could you try to not use the LegacyService directly but use a UIService instead? Does the following Groovy script still result in the described memory error?

// @UIService uiService
// @OpService opService
// @Dataset currentData

import net.imagej.legacy.LegacyService;
import ij.ImagePlus;
import ij.IJ;
import java.lang.System;

// run conversion a few times to demonstrate memory build up
for (int i = 0; i < 25; i++) {
	println(i);
	// convert to float, this makes the issue more obvious
	dataFloat = opService.run("convert.float32", currentData);

	uiService.show("test", dataFloat);
}

// My attempt to clean up
dataFloat = null;
imp = null;
legacy = null;
System.gc();

Best,
Stefan


#3

Hi Stefan

Thank you for the response, its good to know the issue is reproducible.

Your script dosnt result in memory errors however the problem is I dont want to display the data which I think it what the UIService offers? I would like to use various ops commands and then retrieve an ij.ImagePlus object which can be used for IJ1 functionality.

Best
Jeremy


#4

For now, you could use ImgLib2’s ImageJFunctions.wrap(RandomAccessibleInterval<T> img, String title). Although I will admit that this might not be best practice.

Maybe @imagejan is aware of a better way?


#5

Great that seems to work with no memory build up.

Thank you very much.

Jeremy


#6

Thanks for the report, @jpike.

It is definitely unfortunate that the LegacyService causes this issue for you. One of my goals is to eliminate any need to use ImageJFunctions directly.

I guess we should file an issue in imagej-legacy about this. Otherwise I will probably forget, and this thread will fade into the background.