VT-Python - Memory management

import sys
import numpy as np
import vt
from timagetk.io.image import _image_from_url
/builds/J-gEBwyb/0/mosaic/timagetk/src/timagetk/components/labelled_image.py:31: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from tqdm.autonotebook import tqdm

Load a test image

tmp_path = _image_from_url('https://zenodo.org/record/7149218/files/090223-p58-flo-top.lsm',
                           hash_value='5548917d3d1490200d0d56cbb31c0d35', hash_method='md5')
img = vt.vtImage(tmp_path)

Accessing the reference count of a python object:

As Python does NOT have pointers and use reference counts for memory management you may need to know its value for a given object. It is accessible as follow:

sys.getrefcount(img)
2

Tutorial to understand the difference between C++ & Python: https://realpython.com/pointers-in-python/

Official documentation for sys.getrefcount: https://docs.python.org/3.7/library/sys.html#sys.getrefcount

Check vt.Image object memory address

Official documentation for the built-in method id: https://docs.python.org/3.7/library/functions.html#id

id(img)
140154180116976
sys.getrefcount(img)
2
id(img)
140154180116976

=> Same address… this is good!

sys.getrefcount(img)
2

=> The refcount value of the img object is changing (decrease) without any modification… this is weird no ?

id(img)
140154180116976
sys.getrefcount(img)
2
id(img)
140154180116976
sys.getrefcount(img)
2

Check the memory address of .to_array() method

The .to_array() method is supposed to return a pointer, we expect the address to be the same!

id(img.to_array())
140154173393296
id(img.to_array())
140154173392624

=> Not the same… this is NOT good!

#arr = img.copy_to_array()

=> Calling img.copy_to_array() after img.to_array() result in a crash !!!

Check the memory address of .copy_to_array() method

The .copy_to_array() method is supposed to return a numpy.ndarray, we expect the address to change uppon method call!

img = vt.vtImage(tmp_path)
id(img.copy_to_array())
140154173393392
id(img.copy_to_array())
140154173393104
np.testing.assert_array_equal(img.copy_to_array(), img.copy_to_array())

=> As expected, the addresses are different, but the arrays are the same!

Test with python object definition:

arr = img.copy_to_array()
type(arr)
numpy.ndarray
sys.getrefcount(arr)
2
id(arr)
140154172812048
id(arr)
140154172812048

=> As expected, the returned address for a given object is constant!

np.testing.assert_array_equal(arr, img.copy_to_array())
sys.getrefcount(arr)
2

=> As expected, the reference count for the NumPy array object arr is equal to 2. (+1 for the temporary exrta reference to arr by sys.getrefcount as explained in the official documentation).

Test with array modification:

id(arr)
140154172812048
arr[0, 0, 0] = 12
id(arr)
140154172812048

=> As expected the addresses are the same!

Accessing an object size in bytes:

Official documentation for sys.getsizeof: https://docs.python.org/3.7/library/sys.html#sys.getsizeof

sys.getsizeof(img.copy_to_array())
12484544
sys.getsizeof(arr)
12484544

=> As expected the object have the same size!