# Free image memory

**URL:** <https://discourse.itk.org/t/free-image-memory/863>\
**Category:** Engineering\
**Created:** [April 23, 2018, 9:44pm UTC](https://discourse.itk.org/t/free-image-memory/863 "2018-04-23T21:44:30Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gib](https://discourse.itk.org/user_avatar/discourse.itk.org/gib/32/4124_2.png) [@Gib](https://discourse.itk.org/u/Gib)\
**Post date:** [April 23, 2018, 9:44pm UTC](https://discourse.itk.org/t/free-image-memory/863/1 "2018-04-23T21:44:31Z")

</div>

Hi,

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:

typedef itk::Image\<unsigned char,3\> ImageType;  
ImageType::Pointer imskel;

```
typedef itk::ImageFileReader<ImageType> FileReaderType;

// Read skeleton file
FileReaderType::Pointer readerskel = FileReaderType::New();
readerskel->SetFileName(skelFile);
try
{
	printf("Reading input skeleton file: %s\n",skelFile);
	readerskel->Update();
}
catch (itk::ExceptionObject &e)
{
	std::cout << e << std::endl;
	fprintf(fperr,"Read error on skeleton file\n");
	fclose(fperr);
	return 2;	// Read error on input file
}
imskel = readerskel->GetOutput();

pskel = (unsigned char *)(imskel->GetBufferPointer());

```

I work with pskel.

Thanks  
Gib

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [April 24, 2018, 1:02pm UTC](https://discourse.itk.org/t/free-image-memory/863/2 "2018-04-24T13:02:27Z")

</div>

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.

There is a section in the ITK Software Guide about how to write a streaming filter:  
[https://itk.org/ITKSoftwareGuide/html/Book1/ITKSoftwareGuide-Book1ch8.html#x47-1350008.3](https://itk.org/ITKSoftwareGuide/html/Book1/ITKSoftwareGuide-Book1ch8.html#x47-1350008.3)

---

<div class="post-metadata">

**Author:** ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)\
**Post date:** [April 24, 2018, 2:01pm UTC](https://discourse.itk.org/t/free-image-memory/863/3 "2018-04-24T14:01:51Z")

</div>

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;`

---

<div class="post-metadata">

**Author:** ![Gib](https://discourse.itk.org/user_avatar/discourse.itk.org/gib/32/4124_2.png) [@Gib](https://discourse.itk.org/u/Gib)\
**Post date:** [April 24, 2018, 8:47pm UTC](https://discourse.itk.org/t/free-image-memory/863/4 "2018-04-24T20:47:06Z")

</div>

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.

Best regards  
Gib

---

<div class="post-metadata">

**Author:** ![Gib](https://discourse.itk.org/user_avatar/discourse.itk.org/gib/32/4124_2.png) [@Gib](https://discourse.itk.org/u/Gib)\
**Post date:** [April 24, 2018, 10:01pm UTC](https://discourse.itk.org/t/free-image-memory/863/5 "2018-04-24T22:01:47Z")

</div>

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.

Any other suggestions?

---

<div class="post-metadata">

**Author:** ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)\
**Post date:** [April 24, 2018, 10:54pm UTC](https://discourse.itk.org/t/free-image-memory/863/6 "2018-04-24T22:54:07Z")

</div>

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:

```auto
imskel->GetPixelContainer()->SetImportPointer(NULL, 0);

```

---

<div class="post-metadata">

**Author:** ![Gib](https://discourse.itk.org/user_avatar/discourse.itk.org/gib/32/4124_2.png) [@Gib](https://discourse.itk.org/u/Gib)\
**Post date:** [April 25, 2018, 4:01am UTC](https://discourse.itk.org/t/free-image-memory/863/7 "2018-04-25T04:01:52Z")

</div>

Here is what std::cout\<\<imskel produces:

Image (0000000001F69680)  
RTTI typeinfo: class itk::Image\<unsigned char,3\>  
Reference Count: 3  
Modified Time: 189  
Debug: Off  
Object Name:  
Observers:  
none  
Source: (0000000001C7F900)  
Source output name: Primary  
Release Data: Off  
Data Released: False  
Global Release Data: Off  
PipelineMTime: 49  
UpdateMTime: 190  
RealTimeStamp: 0 seconds  
LargestPossibleRegion:  
Dimension: 3  
Index: [0, 0, 0]  
Size: [3219, 1820, 929]  
BufferedRegion:  
Dimension: 3  
Index: [0, 0, 0]  
Size: [3219, 1820, 929]  
RequestedRegion:  
Dimension: 3  
Index: [0, 0, 0]  
Size: [3219, 1820, 929]  
Spacing: [1, 1, 1]  
Origin: [0, 0, 0]  
Direction:  
1 0 0  
0 1 0  
0 0 1

IndexToPointMatrix:  
1 0 0  
0 1 0  
0 0 1

PointToIndexMatrix:  
1 0 0  
0 1 0  
0 0 1

Inverse Direction:  
1 0 0  
0 1 0  
0 0 1

PixelContainer:  
ImportImageContainer (0000000001F12E50)  
RTTI typeinfo: class itk::ImportImageContainer\<unsigned \_\_int64,unsigned  
char\>  
Reference Count: 1  
Modified Time: 187  
Debug: Off  
Object Name:  
Observers:  
none  
Pointer: 000000013F900040  
Container manages memory: true  
Size: 5442620820  
Capacity: 5442620820

---

<div class="post-metadata">

**Author:** ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)\
**Post date:** [April 25, 2018, 2:37pm UTC](https://discourse.itk.org/t/free-image-memory/863/8 "2018-04-25T14:37:57Z")

</div>

> [@Gib](#):
>
> Reference Count: 3

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.

---

<div class="post-metadata">

**Author:** ![Gib](https://discourse.itk.org/user_avatar/discourse.itk.org/gib/32/4124_2.png) [@Gib](https://discourse.itk.org/u/Gib)\
**Post date:** [April 25, 2018, 8:30pm UTC](https://discourse.itk.org/t/free-image-memory/863/9 "2018-04-25T20:30:09Z")

</div>

Hi Dzenan,

Here are all the code lines that mention imskel:

ImageType::Pointer im, imskel;

…

```
imskel = readerskel->GetOutput();

width = imskel->GetLargestPossibleRegion().GetSize()[0];

height = imskel->GetLargestPossibleRegion().GetSize()[1];

depth = imskel->GetLargestPossibleRegion().GetSize()[2];

pskel = (unsigned char *)(imskel->GetBufferPointer());

```

Can you see how there are 3 references? Maybe pskel needs to be freed first.

Thanks

Gib

---

<div class="post-metadata">

**Author:** ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)\
**Post date:** [April 25, 2018, 8:37pm UTC](https://discourse.itk.org/t/free-image-memory/863/10 "2018-04-25T20:37:42Z")

</div>

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:

```auto
{
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

```

---

<div class="post-metadata">

**Author:** ![Gib](https://discourse.itk.org/user_avatar/discourse.itk.org/gib/32/4124_2.png) [@Gib](https://discourse.itk.org/u/Gib)\
**Post date:** [April 25, 2018, 8:56pm UTC](https://discourse.itk.org/t/free-image-memory/863/11 "2018-04-25T20:56:25Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Gib](https://discourse.itk.org/user_avatar/discourse.itk.org/gib/32/4124_2.png) [@Gib](https://discourse.itk.org/u/Gib)\
**Post date:** [April 25, 2018, 11:35pm UTC](https://discourse.itk.org/t/free-image-memory/863/12 "2018-04-25T23:35:36Z")

</div>

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();

This is success!

Thanks!

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [April 25, 2018, 11:41pm UTC](https://discourse.itk.org/t/free-image-memory/863/13 "2018-04-25T23:41:22Z")

</div>

Are you holding onto the filter that generated the image?

---

<div class="post-metadata">

**Author:** ![Gib](https://discourse.itk.org/user_avatar/discourse.itk.org/gib/32/4124_2.png) [@Gib](https://discourse.itk.org/u/Gib)\
**Post date:** [April 25, 2018, 11:47pm UTC](https://discourse.itk.org/t/free-image-memory/863/14 "2018-04-25T23:47:05Z")

</div>

If I understand your question, the image is generated by the reader, e.g.:

typedef itk::ImageFileReader ImageReaderType;

```
{

    ImageReaderType::Pointer reader = ImageReaderType::New();

    reader->SetFileName(infile);

    reader->Update();

    im = reader->GetOutput();

}
```
