Difference between revisions of "Documentation/Nightly/Developers/Tutorials/MemoryManagement"

From Slicer Wiki
Jump to: navigation, search
(Prepend documentation/versioncheck template. See http://na-mic.org/Mantis/view.php?id=2887)
(Moved to readthedocs)
Tags: 2017 source edit, Replaced
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
<noinclude>{{documentation/versioncheck}}</noinclude>
 
<noinclude>{{documentation/versioncheck}}</noinclude>
From http://massmail.spl.harvard.edu/public-archives/slicer-devel/2011/007513.html
 
  
Like VTK, Slicer contains some "factory" methods:
+
{{documentation/banner
  - vtkMRMLScene::CreateNodeByClass()
+
| text = [https://slicer.readthedocs.io/en/latest/developer_guide/advanced_topics.html#memory-management This page has been moved to read-the-docs.]
- vtkMRMLScene::GetNodesByClass()
+
| background-color = 8FBC8F }}
- ...
 
Like in C++, it means that the functions return an object with a reference
 
count of 1 that nobody "owns" and the caller must take care of releasing
 
the object to avoid memory leak.
 
 
 
While there is workaround for some methods (
 
slicer.mrmlScene.CreateNodeByClass('vtkMRMLModelNode') should be replaced
 
by slicer.vtkMRMLModelNode() ) there is currently no automatic/clean
 
mechanism to release the object created by such methods.
 
 
 
The only "hack" that exists for now is to decrease the reference count
 
manually in your code:
 
 
 
nodes = slicer.mrmlScene.GetNodesByClass('vtkMRMLLinearTransformNode')
 
nodes.UnRegister(slicer.mrmlScene)      # ----> (reference count was 2, keep 1 for the python reference)
 
...
 
 
 
In C++, the following would apply:
 
vtkCollection* nodes =
 
mrmlScene->GetNodesByClass("vtkMRMLLinearTransformNode");
 
...
 
nodes->Delete();
 
 
 
or using vtkSmartPointer:
 
vtkSmartPointer<vtkCollection> nodes;
 
nodes.TakeReference(mrmlScene->GetNodesByClass("vtkMRMLLinearTransformNode"));
 
...
 
 
 
Amendment from JC http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=19772
 
 
 
The reference count shouldn't be decreased using the naive approach where
 
it is set to one. Indeed, internally, the reference count could be any
 
number greater than one. It doesn't have to be 2.
 
 
 
Considering this last remark, using the following approach is *REQUIRED*,
 
otherwise it will lead to a CRASH of the application.
 
 
 
n = slicer.mrmlScene.CreateNodeByClass('vtkMRMLViewNode')
 
slicer.mrmlScene.addNode(n)
 
n.UnRegister(slicer.mrmlScene)
 
 
 
Even better, this specific example can be simplified using the following
 
syntax, this is the *RECOMMENDED* approach, it will prevent bug, memory
 
leaks and crashes:
 
 
 
  n = slicer.mrmlScene.addNode(slicer.vtkMRMLViewNode())
 
 
 
And if the name of the node is generated at runtime, this could be done:
 
 
 
  n = eval('slicer.mrmlScene.AddNode(slicer.%s())' % 'vtkMRMLViewNode')
 

Latest revision as of 20:02, 4 February 2022

Home < Documentation < Nightly < Developers < Tutorials < MemoryManagement