Python脚本中的内存泄漏问题在Blender中。

3
我是一名相对新手的Python开发者(平时使用C ++)。 我编写了一个Python脚本,使用光线跟踪算法将Blender对象转换为二进制掩码文件。
然而,我遇到了严重的内存泄漏问题。当M = 512时(如下所示),随着脚本的运行,RAM使用量增加,最终使用5.7GB的内存。即使在脚本运行完毕后,RAM使用量仍然保持不变,直到我关闭Blender程序。
我不确定open()命令是否将打开的文件存储在RAM中(我猜测它会),但这只占256MB的RAM使用量,因为这是生成的文件大小,并且也无法解释为什么fo.close()后,RAM使用量仍然保持不变。
我肯定错过了一些非常简单的东西,但由于对Python不太熟悉,我很难弄清楚是什么。我尝试通过添加以下代码清空pointInsideMesh()函数中使用的所有变量:
axis  = None
mat1  = None
mat   = None
orig  = None
count = None
location = None
normal   = None
index    = None
outside1 = None
outside2 = None

在`return`语句之前立即调用该函数,但这并没有解决内存泄漏问题。以下是我的代码:
import mathutils, numpy, bpy





def pointInsideMesh(point,ob):

    axes = [ mathutils.Vector((1,0,0)) ]
    outside1 = False
    for axis in axes:

        mat1 = mathutils.Matrix(ob.matrix_world)
        mat=mat1.invert()

        orig = mat1*point


        count = 0
        while True:
            location,normal,index = ob.ray_cast(orig,axis*10000.0)
            if index == -1: break
            count+= 1

            orig = location + axis*0.00001



        if (count%2 == 0):
            outside1 = True
            break




    axes = [ mathutils.Vector((0,1,0)) ]
    outside2 = False
    for axis in axes:

        mat1 = mathutils.Matrix(ob.matrix_world)
        mat=mat1.invert()

        orig = mat1*point


        count = 0
        while True:
            location,normal,index = ob.ray_cast(orig,axis*10000.0)
            if index == -1: break
            count+= 1

            orig = location + axis*0.00001



        if (count%2 == 0):
            outside2 = True
            break

    outside = outside1 or outside2
    return not outside




ob = bpy.context.active_object
M = 512
fileOut = 'D:\images\\maskFile.txt'

fo = open(fileOut , "w")
for n in range(0,M):
    for m in range(0,M):
        for l in range(0,M):
            if pointInsideMesh( mathutils.Vector(((l+1)/M-0.5,(m+1)/M-0.5,(n+1)/M-0.5)), ob ):
                fo.write("1")
            else:
                fo.write("0")
            if l < M-1:
                fo.write(" ")
        fo.write("\n") 
    fo.write("\n")          
fo.close()

任何帮助都将不胜感激 :)
更新:
import mathutils, numpy, bpy

def pointInsideMesh(point,ob):
    return False

ob = bpy.context.active_object
M = 512
fileOut = 'D:\images\\maskFile.txt'

fo = open(fileOut , "w")
for n in range(0,M):
    for m in range(0,M):
        for l in range(0,M):
            if pointInsideMesh( mathutils.Vector(((l+1)/M-0.5,(m+1)/M-0.5,(n+1)/M-0.5)), ob ):
                fo.write("1")
            else:
                fo.write("0")
            if l < M-1:
                fo.write(" ")
        fo.write("\n") 
    fo.write("\n")          
fo.close()

重现了问题,但是

import mathutils, numpy, bpy

def pointInsideMesh():
    return False

ob = bpy.context.active_object
M = 512
fileOut = 'D:\images\\maskFile.txt'

fo = open(fileOut , "w")
for n in range(0,M):
    for m in range(0,M):
        for l in range(0,M):
            if pointInsideMesh():
                fo.write("1")
            else:
                fo.write("0")
            if l < M-1:
                fo.write(" ")
        fo.write("\n") 
    fo.write("\n")          
fo.close()

两个例子中唯一的区别是,在第一个例子中,被测试点(和对象)的位置被传递到函数中,而在第二个例子中,没有传递任何参数。在C++中,即使按值传递,函数内创建的参数副本也会在函数返回时从内存中清除。但在Python中,参数传递方式不同,这可能是问题的根源,因为我真的不理解这是如何工作的。


在最后的两个不同版本中,mathutils.Vector对我来说有点可疑。除非垃圾回收器有问题,否则传递变量不会导致内存泄漏。 - undefined
顺便说一句,我在Blender 3.6.5上无法复现这个问题。 - undefined
1个回答

0

导致内存泄漏的唯一可能是ob对象。

你对该对象进行了512^3次操作。如果ob.ray_castob对象上存储了一些数据,那么可能就是问题所在。尝试替换

ob.ray_cast(orig,axis*10000.0)

使用3个静态值,看看内存问题是否仍然存在。Blender的C端可能存在内存泄漏。


感谢您的评论。我最初尝试了这个,但它没有起作用,但是我已经进行了更重大的更改,以尝试确定泄漏发生的位置。这可以在我原始问题的更新中看到。再次感谢 :) - Zac-K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接