[Closed] .net sdk memory management problem
Hoi!
I’m diving into the sdk to speed up some routines and have this function that leaks a lot of memory. The function, that is called on each frame, takes an editable mesh and sets the vertex colors based on some criteria. Can anyone spot what I’m doing wrong here?
public void GradeMesh()
{
IObject obj = node.EvalWorldState(ip.Time, true).Obj;
IClass_ID cid = global.Class_ID.Create((uint)BuiltInClassIDA.TRIOBJ_CLASS_ID, 0);
if (obj.CanConvertToType(cid) != 0)
{
ITriObject triMesh = obj.ConvertToType(ip.Time, cid) as ITriObject;
IMesh mesh = triMesh.Mesh;
IList<IPoint3> mapVerts = mesh.MapVerts(Channel);
int numMapVerts = mesh.GetNumMapVerts(Channel);
for (int i = 0; i < numMapVerts; i++)
{
IPoint3 vertex = mesh.GetVert(i);
IPoint3 mapVert = mapVerts[i];
float r = mapVert.X * 255.0f;
float g = mapVert.Y * 255.0f;
float b = mapVert.Z * 255.0f;
if (vertex.Z > HeightThreshold)
{
float newG = Math.Max(0, (g - FadeInValue) / 255);
float newB = Math.Max(0, (b - FadeInValue) / 255);
mesh.SetMapVert(Channel, i, global.Point3.Create(1, newG, newB));
}
else if (g < 255)
{
if (g + FadeOutValue > 255)
mesh.SetMapVert(Channel, i, global.Point3.Create(1, 1, 1));
else
mesh.SetMapVert(
Channel, i, global.Point3.Create(
1, (g + FadeOutValue) / 255, (g + FadeOutValue) / 255));
}
}
triMesh.Dispose();
mesh.Dispose();
}
obj.Dispose();
}
thanks!
i don’t know .net sdk well but in c++ you have to delete TriObject after use.
something like:
TriObject *tri = (TriObject *)ob->ConvertToType(MAXScript_time(), triObjectClassID);
/** do things *******/
if (ob != tri) tri->AutoDelete();
oops… i see you do .Dispose(). it deletes the triObject, but nothing can guaranty that it does do garbage collection.
as i see c# function is not undoable in itself. what do you do to make it undoable?
The mxs version did perform well on ~1k vertices, but it had problems with anything much higher than that. The .net function runs at 15 fps on my old machine with 100k vertices.
I have not even thought about making it undoable, but I guess that don’t matter since it is evaluated at each time step
There is a bug in MaxScript when setting the vertex colors of a mesh using the meshop methods. The bug may extend to poly if we talk about performance.
Using default mesh operations on default color channels performs fast and clean.
The same using meshop is much slower and there is a huge leak of memory. The leak does not happen in the MaxScript Heap. But on the system memory.
The polyop version does not leak too much, but it is twice as slow as the meshop operation.
Here are some tests:
(
gc()
delete objects
node = converttomesh (geosphere showvertexcolors:on)
defaultvcfaces node
st = timestamp(); sh = heapfree
for i = 1 to 100000 do setvertcolor node (random 1 node.numverts) (random black white)
format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
)
– time:91 ram:128L
Meshop version
Watch the System Memory when running the following as Max might crash without advice.
(
gc()
delete objects
node = converttomesh (geosphere showvertexcolors:on vertexcolortype:5 vertexcolormapchannel:1)
channel = 1
meshop.defaultmapfaces node channel
meshop_setvertcolor = meshop.setvertcolor
st = timestamp(); sh = heapfree
for i = 1 to 100000 do meshop_setvertcolor node channel (random 1 node.numverts) (random black white)
format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
)
– time:1452 ram:128L[color=DarkOrange] / 1.3 Gb of RAM
[/color]
Polyop version:
(
gc()
delete objects
node = converttopoly (geosphere showvertexcolors:on vertexcolortype:5 vertexcolormapchannel:1)
channel = 1
polyop.defaultmapfaces node channel
polyop_setvertcolor = polyop.setvertcolor
st = timestamp(); sh = heapfree
for i = 1 to 100000 do polyop_setvertcolor node channel (random 1 node.numverts) (random black white)
format "time:% ram:%
" (timestamp()-st) (sh-heapfree)
)
– time:2786 ram:128L
Now that you mention this, the bug could perhaps be in the Max core?
meshop.setvertcolor
is very slow method (the same for polyop). there is a post where i explained why it’s slow. so instead of using
setvertcolor
use setmapvert for a specified channel
Thank you Denis. Yes I am aware of the meshop.setmapvert function, although I never needed to use it so I just use setvertcolor, which is much faster.
Even when meshop.setvertcolor is over 20 times slower than setvertcolor, there is a bug that leaks a lot of memory.
There are not too many bugs that leak as much memory as this one in MaxScript that I am aware of.
hehhh… i have to tell it again… setvertcolor is a GEO index based function, but the value is set to a MAP channel vert(s)
so the setvertcolor function with EVERY call looks a geo-map-geo vert corresponding. it’s very-very slow.
And here we go again... I don't know what MaxScript you are talking about, but in my version there is no "setmapvert" function except the one in the meshop struct "meshop.setmapvert".
Now, this allows you to use a different channels than the default ones. That's the only difference I know it has compared with the pure "setvertcolor" (not meshop.setvertcolor).
So, as I don't need to use another color vertex channel than 1, I just use set vertcolor, because "meshop.setmapvert" is much slower.
Does that make sense or I am missing something?
EDITED: Added code for comparison:
(
/* SETVERTCOLOR */
delete objects
node = converttomesh (geosphere showvertexcolors:on)
defaultvcfaces node
gc(); seed 1
st = timestamp(); sh = heapfree
for i = 1 to 100000 do setvertcolor node (random 1 node.numverts) (random black white)
format "setvertcolor: %ms ram:%
" (timestamp()-st) (sh-heapfree)
/* MESHOP.SETMAPVERT */
node = converttomesh (geosphere showvertexcolors:on vertexcolortype:5 vertexcolormapchannel:1 pos:[60,0,0])
channel = 1
meshop.defaultmapfaces node channel
gc(); seed 1
st = timestamp(); sh = heapfree
meshop_setmapvert = meshop.setmapvert
for i = 1 to 100000 do meshop_setmapvert node channel (random 1 node.numverts) ((random black white)/255)
format "meshop.setmapvert: %ms ram:%
" (timestamp()-st) (sh-heapfree)
)
– setvertcolor: 78ms ram:120L
– meshop.setmapvert: 172ms ram:192L