I am working with very big images (> 5GB) and running out of memory. I’d like to know how I should free the memory used by an image that I’ve read, after I no longer need it.
My code looks like this:
ITK’s pipeline features streaming support, which is the ability to request a sub-region and only provide that sub-region. Algorithms can be witting which iteratively process these sub-regions or chunks one at a time.
I doubt you can have your image like that. When readerskel and imskel go out of scope, the image will be deleted. So in addition to keeping pskel you should also keep an image smart pointer (imskel), and delete that when you need the memory freed. A simple way to delete the image is imskel = ImageType::New();, which assigns a new image which does not have its buffer allocated to imskel smart pointer, which in turn deletes the last reference to the old image so it is deleted and its buffer is freed.
Edit: even better way to delete is imskel = nullptr;
Thanks for the responses. Dzenan, both imskel and pskel are global variables and pskel is used in many places. readerskel is not global, so it goes out of scope, but that apparently causes no problems.
I’ll try your suggestion of imskel = nullptr.
The streaming filter option looks interesting, Bradley, but it might be non-trivial to fit it into the way my program works.
Unfortunately, on Windows neither method of freeing image memory works (for me). On Linux assigning a new image doesn’t work, and “nullptr is not declared in this scope”. I gather it may be possible to jump through some hoops to make nullptr declared, but since it doesn’t have effect on Windows it doesn’t seem worth the effort.
If that doesn’t free your image, you might have more references to it. Can you print it std::cout<<imskel; to see its reference count? If you want to force-free it, you might do something like:
You probably have some other smart pointers to that image then. You can forcefully reduce the reference count by imskel->UnRegister();, but that might cause a crash in your program because you will probably have some dangling pointers once your image has been deallocated.
I don’t think GetBufferPointer() causes additional references. You can check that by printing imskel before and after assigning pskel. But remember that readerskel has one reference to the image. You should examine reference count outside of the function (or at least block) which creates the reader. Something like:
{
ReaderType::Pointer reader=ReaderType::New();
...
imskel = reader->GetOutput();
imskel->DisconnectPipeline();
} //closing block destructs the reader and should reduce reference count
std::cout<<imskel; //check reference count
I printed imskel in a function after the last usage of pskel (the code I showed is in main.) readerskel is local to main, but imskel and pskel are global in scope.
I will run the more extensive tests you’ve suggested later.
I have run some tests. Putting readerskel in a block has the effect of reducing the number of references from 3 to 2, and allows either method (setting imskel to nullptr or ImageType::New()) to free the memory. This is unaffected by assigning pskel to point to the image buffer, and also unaffected by imskel->DisconnectPipeline();