Gio.MemoryInputStream 关闭时不释放内存
Gio.MemoryInputStream does not free memory when closed
运行 Python 3.4 on Windows 7,Gio.MemoryInputStream 的关闭函数没有释放内存,这是应该的。测试代码为:
from gi.repository import Gio
import os, psutil
process = psutil.Process(os.getpid())
for i in range (1,10) :
input_stream = Gio.MemoryInputStream.new_from_data(b"x" * 10**7)
x = input_stream.close_async(2)
y = int(process.memory_info().rss / 10**6) # Get the size of memory used by the program
print (x, y)
这个 returns :
True 25
True 35
True 45
True 55
True 65
True 75
True 85
True 95
True 105
这表明在每个循环中,程序使用的内存增加 10 MB,即使关闭函数返回 True 也是如此。
一旦 Stream 关闭,如何释放内存?
另一个好的解决方案是重用流。但是 set_data 或 replace_data 会引发以下错误:
'Data access methods are unsupported. Use normal Python attributes instead'
很好,但是哪个 属性 ?
我需要 Python 3.4 中的内存流。我用 PyPDF2 创建了一个 Pdf 文件,然后我想用 Poppler 预览它。由于 Poppler 中的错误(请参阅 ),我无法使用 new_from_data 函数,而想使用 new_from_stream 函数。
这是 a bug in GLib’s Python bindings,无法轻易修复。
相反,您应该使用 g_memory_input_stream_new_from_bytes()
,它以不同方式处理释放内存,并且不会出现相同的错误。
更详细地说,new_from_data()
的错误是由 introspection annotations 引起的,GLib 使用它允许语言绑定自动公开其所有 API,不支持 GDestroyNotify
new_from_data()
的参数需要设置为非 NULL
函数以释放传递给其他参数的已分配内存。 运行 您在 gdb
下的脚本显示 pygobject 将 NULL
传递给 GDestroyNotify
参数。它不能做得更好,因为目前没有办法表达 data
参数的内存管理语义取决于传递给 destroy
.
的内容
感谢您的回答,@Philip Withnall。我测试了您提出的解决方案,并且有效。为了帮助其他人理解,这是我的测试代码:
from gi.repository import Gio, GLib
import os, psutil
process = psutil.Process(os.getpid())
for i in range (1,10) :
input_stream = Gio.MemoryInputStream.new_from_bytes(GLib.Bytes(b"x" * 10**7))
x = input_stream.close()
y = int(process.memory_info().rss / 10**6) # Get the size of memory used by the program
print (x, y)
现在y不再增长了。
运行 Python 3.4 on Windows 7,Gio.MemoryInputStream 的关闭函数没有释放内存,这是应该的。测试代码为:
from gi.repository import Gio
import os, psutil
process = psutil.Process(os.getpid())
for i in range (1,10) :
input_stream = Gio.MemoryInputStream.new_from_data(b"x" * 10**7)
x = input_stream.close_async(2)
y = int(process.memory_info().rss / 10**6) # Get the size of memory used by the program
print (x, y)
这个 returns :
True 25
True 35
True 45
True 55
True 65
True 75
True 85
True 95
True 105
这表明在每个循环中,程序使用的内存增加 10 MB,即使关闭函数返回 True 也是如此。 一旦 Stream 关闭,如何释放内存?
另一个好的解决方案是重用流。但是 set_data 或 replace_data 会引发以下错误: 'Data access methods are unsupported. Use normal Python attributes instead' 很好,但是哪个 属性 ?
我需要 Python 3.4 中的内存流。我用 PyPDF2 创建了一个 Pdf 文件,然后我想用 Poppler 预览它。由于 Poppler 中的错误(请参阅
这是 a bug in GLib’s Python bindings,无法轻易修复。
相反,您应该使用 g_memory_input_stream_new_from_bytes()
,它以不同方式处理释放内存,并且不会出现相同的错误。
更详细地说,new_from_data()
的错误是由 introspection annotations 引起的,GLib 使用它允许语言绑定自动公开其所有 API,不支持 GDestroyNotify
new_from_data()
的参数需要设置为非 NULL
函数以释放传递给其他参数的已分配内存。 运行 您在 gdb
下的脚本显示 pygobject 将 NULL
传递给 GDestroyNotify
参数。它不能做得更好,因为目前没有办法表达 data
参数的内存管理语义取决于传递给 destroy
.
感谢您的回答,@Philip Withnall。我测试了您提出的解决方案,并且有效。为了帮助其他人理解,这是我的测试代码:
from gi.repository import Gio, GLib
import os, psutil
process = psutil.Process(os.getpid())
for i in range (1,10) :
input_stream = Gio.MemoryInputStream.new_from_bytes(GLib.Bytes(b"x" * 10**7))
x = input_stream.close()
y = int(process.memory_info().rss / 10**6) # Get the size of memory used by the program
print (x, y)
现在y不再增长了。