Pyglet 内存泄漏 & 页面错误 以及(可能)有用的解决方法

Charapter 1: 端倪

最近一直在用Pyglet做一个小的案例,但是实际运行起来时发现了严重的内存泄漏。经调查后发现平均每秒会爆出80-120不等的页面错误。且可以观察到内存正在不断地以0.2-0.4mb不等的速度增长

能够复原此问题的代码如下:

# 导入库
import pyglet
win = pyglet.window.Window()

# 注册函数
@win.event('on_draw')
def Draw():
	# 绘制一个白色的正方形
	pyglet.shapes.Rectangle(0, 0, 100, 100, color = (255, 255, 255, 255)).draw()

# 使程序运行
pyglet.app.run()

在程序启动后,能够明显发现内存在不断增加。如下图:



(第二空为pid,第三空为提交内存,第四空和第五空分别为页面错误总数和页面错误增量)

Charapter 2: 调试

后来,在查阅一些资料后,发现了Pyglet存在"双缓冲区机制"(这个机制给我的感觉就是可有可无,还请大佬在评论区赐教),试图去掉双缓冲区后代码如下:

# 导入库
import pyglet
win = pyglet.window.Window(config = pyglet.gl.Config(double_buffer = False)) # 去掉双缓冲

# 注册函数
@win.event('on_draw')
def Draw():
	# 绘制一个白色的正方形
	pyglet.shapes.Rectangle(0, 0, 100, 100, color = (255, 255, 255, 255)).draw()

# 使程序运行
pyglet.app.run()




(第一张和第三张为正常使用时的图片,第二张为突发帧,相较之前错误少了一半)

看上去像是好一点了。

Charapter 3: 削除

仍然会有泄露的问题。观察了下gc,发现字典,元组和函数的数量在不断增加。而一个最简单的示例里就没有这些问题。我想了好一阵,两个示例里最大的差别就是,在之前的示例中,on_draw()函数执行了在窗口上绘制了白色正方形的任务。所以,问题有没有可能出在正方形上呢?

将示例中的正方形删掉之后,错误立即减少了许多。一直降至0-1。问题修复了。由此可知:函数内不能创建Pyglet的任何图形对象。

之后,尝试在函数外就先创建一个正方形,果然没有了问题。

热门相关:你是我生命的四分之三   战国明月   我的绝色美女房客   原来你喜欢我呀   女士邀请函   司令,以权谋妻