Hello Dynamo users and Dynamo package developers,
We’ve been working for a while on improving the stability of the Dynamo geometry library. A major stumbling block for developing stable Dynamo packages - both internal to Autodesk and for external node and package authors is the requirement that memory be managed manually when using Dynamo Geometry types from python and c# .
The dreaded system access violation or mysterious hang and crash of Revit/Dynamo!
A small snippet that reproduces the issue in python is:
for i in range(100000): x = Cuboid.ByLengths(0,0,0) OUT = "some string"
If you are not familiar with garbage collection - the idea here is that the runtime (in this case .net) detects that the cubes have gone out of scope, and cannot be referenced from anywhere else in your code, including the Dynamo graph - because they have not been returned - and tries to clean their memory up.
Unfortunately, this causes issues with the Dynamo geometry library, and as advised in the link above, should be avoided by manually calling
dispose() on geometry that is not returned or referenced.
This is a pretty big burden when writing exploratory code, and hard to get right.
Well, I have some good news.
In the latest daily builds of Dynamo master ( DynamoCoreRuntime_18.104.22.16845 ) - we have removed the requirement for you to manually manage memory for most use cases.
But what’s the catch?
There are some complex use cases that still require manual disposal, and during our investigation into this issue we believe we have identified some good rules to follow:
If you are using the Dynamo Geometry library namespaces ( Autodesk.DesignScript.Geometry - ie ProtoGeometry.dll ) - from c# or python and you are not spinning up your own threads, or using classes which create threads (Task, Thread, Parallel etc) - then you should be safe to no longer manually dispose geometry which you do not return - Dynamo will do it for you safely.
If you are using Autodesk.DesignScript.Geometry classes, and you are using them in a multi-threaded way - you are still responsible for disposing of that geometry which you do not return into the graph or hold onto in your classes. You must do this on the same threads which you created the geometry!
The multi-threaded safety of LibG has not been satisfactorily tested, and we have never guaranteed its thread safety, and are not doing so now.
You are still free to manually dispose geometry if you want to and have determined it is the best option for your use case. This means, you don’t need to update your packages to take advantage of this fix! If you are writing a library for others to use, manually disposing is still a good practice.
What do we need from you?
We need some help testing this change, as it is a fundamental change to the geometry library. If you have a graph using packages, zero touch nodes, or python nodes that create geometry - and you have seen the crashing behavior described above as you run this graph on larger sets of geometry, we would love to hear your feedback after you try out the latest daily build.
You’ll need to run these tests in sandbox, so no Revit interactions of course (unless you want to move some dlls around)
Please check out these changes in the latest daily build and let us know what you think or if you find any improvements or strange behavior. We are still internally profiling and testing this change, but wanted to get it out for feedback now.