[Closed] Keeping Max memory clean & lean during batch preview render
I’ve written a batch process that reads a list of max file paths
it reads each path, opens the file, builds an AVI preview, and then moves on to the next file.
Something is leaking memory in this process:
max stalls out and the task manager reports max consuming over a GB of 1000 MB
I’m trying a several commands that should clear up max’s ram load but I’m missing something.
I am saving each AVI across the network, if that makes any difference…
fn doBatch=(
for each in fileList do
(
resetmaxfile #noPrompt --reset the file
gc()--garbage collect
freescenebitmaps() --clean up in texture memory
clearUndoBuffer()-- remove undo
--what else??
SetQuietMode true
if loadMaxFile each quite:true then (
makeAVIpreview()
)
)
)
--here's the AVI preview function
fn makeAVIpreview height:480 = (
previewFilePath = "//server/path/to/previews/"+(substitutestring maxfilename ".max" ".avi")
view_size = getViewSize()
_scale=(height/view_size.y)
anim_bmp = bitmap (_scale*view_size.x) (_scale*view_size.y) filename: previewFilePath
for t = animationrange.start to animationrange.end do
(
sliderTime = t
dib = viewport.getViewportDib()
dib.filename = (getdir #temp) + "\ emp_dib.bmp"
save dib
copy dib anim_bmp
save anim_bmp
)
close anim_bmp
gc()
format "saved:%..." (filenamefrompath previewFilePath) to:previewBatch.blog
)
This is a known thing when it comes to this type of batch processing.
Max cannot just ‘unload’ all the ram it has been using, so it will be higher then when you start 3dsmax the firsts time.
One way to avoid it, is to write it out as a batch file, which then loads max, loads the scene and script, does it’s thing, then closes and repeats.
But that will take more time.
Are you sure it’s not your core for loop in “makeAVIpreview()” leaking ?
I see you do
dib = viewport.getViewportDib()
which allocates a bitmap each loop iteration
GC will have no chance to kick in as long as the loop is busy ( except when the heap space gets to its limits, but i think bitmaps are’nt even allocated on the heap). I would declare “dib” outside the for loop as local dib and place a free dip as last line in the for loop
@SpaceFrog : thnaks for the tip, I’ll try this
fn makeAVIpreview height:480 = (
previewFilePath = "//server/path/to/previews/"+(substitutestring maxfilename ".max" ".avi")
view_size = getViewSize()
_scale=(height/view_size.y)
anim_bmp = bitmap (_scale*view_size.x) (_scale*view_size.y) filename: previewFilePath
local dib
for t = animationrange.start to animationrange.end do
(
sliderTime = t
dib = viewport.getViewportDib()
dib.filename = (getdir #temp) + "\ emp_dib.bmp"
save dib
copy dib anim_bmp
save anim_bmp
)
close anim_bmp
free dib
gc()
format "saved:%..." (filenamefrompath previewFilePath) to:previewBatch.blog
)
The following modifications seems to fix all leaking:
fn makeAVIpreview height:480 = (
previewFilePath = "//server/path/to/previews/"+(substitutestring maxfilename ".max" ".avi")
view_size = getViewSize()
_scale=(height/view_size.y)
anim_bmp = bitmap (_scale*view_size.x) (_scale*view_size.y) filename:previewFilePath
local getviewportdib = gw.getviewportdib
for t = animationrange.start to animationrange.end do
(
sliderTime = t
dib = getviewportdib()
dib.filename = (getdir #temp) + "\ emp_dib.bmp"
save dib
copy dib anim_bmp
save anim_bmp
free dib
)
close anim_bmp
gc()
format "saved:%..." (filenamefrompath previewFilePath) to:previewBatch.blog
)
If you put the “local dib” outside the loop and free it after the loop, it will keep accumulating each new image until the end of the loop. For very long animations it might take a lot of RAM.
If you keep the dib inside the loop instead and free it when it’s no longer needed, memory usage will stay low.
getViewportDib() don’t necessarily needs to be cached, but it might help to speed it up a little.
So basically, “free dib” inside the loop is all you should need to prevent the memory leaking.
Oh yes, how could I miss that!?
But it really does not cause any memory leaking.
Hmm… no dice, I’m still getting RAM bloat.
I’ll try a windows batch command
[edit] oops, did not see the last 3 posts.
[edit 2]
trying Dennis’ version, and the batch is no longer crashing.
however, according to Windows Task Manager’s Process window the RAM consumed by 3dSmax is still shooting up. Not sure what ‘s going on there.
If the “free dib” line inside the loop doesn’t keep the memory low, couldn’t it be another thing? Have you tried with an empty scene of the same animation length?
In my case, freeing the image inside the loop makes the RAM usage stay where it is from the start to the end of the process.
also i don’t understand why do you assign filename to dib bitmap and save dib?
if has to be just:
for ...
(
slidertime = t
dib = gw.getViewportDib()
copy dib avi
save avi
free dib -- not really necessary
)
close avi
It might not be necesary for you, but in my case that single line makes the whole difference between leaking and not.