是内存泄露还是我不懂垃圾回收和内存管理?
Is there a memory leak or do I not understand garbage collection and memory management?
这是我正在使用的第三方库中的内存泄漏,还是我不了解Python垃圾收集和内存管理方面的内容?
最后,我假设内存使用量接近开始时的内存使用量 (33MB),因为我没有对在 do_griddly_work()
中创建的对象的任何引用。但是,内存使用率更高(1600MB),并且在退出函数或收集垃圾后不会下降。
这是打印出来的
Before any work: 33.6953125 MB
After griddly work: 1601.60546875 MB
0
After garbage collect: 1601.60546875 MB
通过以下代码
from griddly import GymWrapperFactory, gd, GymWrapper
import gc
import os, psutil
def do_griddly_work():
current_path = os.path.dirname(os.path.realpath(__file__))
env = GymWrapper(current_path + '/griddly_descriptions/testbed1.yaml',
player_observer_type=gd.ObserverType.VECTOR,
global_observer_type=gd.ObserverType.SPRITE_2D,
level=0)
env.reset()
for _ in range(10000):
c_env = env.clone()
# Print memory usage after work
print('After griddly work: ', psutil.Process(os.getpid()).memory_info().rss / 1024 ** 2, 'MB')
if __name__ == '__main__':
process = psutil.Process(os.getpid())
# Memory usage before work = ~33MB
print('Before any work: ', process.memory_info().rss / 1024 ** 2, 'MB')
# Do work that clones an environment a lot
do_griddly_work()
# Collect garbage
print(gc.collect())
# Memory usage after work = ~1600 MB
print('After garbage collect: ', process.memory_info().rss / 1024 ** 2, 'MB')
大多数语言,包括 Python,都没有义务在对象被销毁后将内存释放回 OS。事实上,因为 OS 分配通常是在比单个对象大得多的块中进行的,该块将包含多个对象,如果其中任何一个仍然存在,它将 不可能 到 return 它到 OS.
memory_info().rss
从 OS 的角度报告已用内存,而不是 Python 运行时的角度。
问题已被我使用的 Griddly 库的作者解决。 Python 垃圾回收无法访问克隆的环境,底层 C++ 实现中存在内存泄漏。
这是我正在使用的第三方库中的内存泄漏,还是我不了解Python垃圾收集和内存管理方面的内容?
最后,我假设内存使用量接近开始时的内存使用量 (33MB),因为我没有对在 do_griddly_work()
中创建的对象的任何引用。但是,内存使用率更高(1600MB),并且在退出函数或收集垃圾后不会下降。
这是打印出来的
Before any work: 33.6953125 MB
After griddly work: 1601.60546875 MB
0
After garbage collect: 1601.60546875 MB
通过以下代码
from griddly import GymWrapperFactory, gd, GymWrapper
import gc
import os, psutil
def do_griddly_work():
current_path = os.path.dirname(os.path.realpath(__file__))
env = GymWrapper(current_path + '/griddly_descriptions/testbed1.yaml',
player_observer_type=gd.ObserverType.VECTOR,
global_observer_type=gd.ObserverType.SPRITE_2D,
level=0)
env.reset()
for _ in range(10000):
c_env = env.clone()
# Print memory usage after work
print('After griddly work: ', psutil.Process(os.getpid()).memory_info().rss / 1024 ** 2, 'MB')
if __name__ == '__main__':
process = psutil.Process(os.getpid())
# Memory usage before work = ~33MB
print('Before any work: ', process.memory_info().rss / 1024 ** 2, 'MB')
# Do work that clones an environment a lot
do_griddly_work()
# Collect garbage
print(gc.collect())
# Memory usage after work = ~1600 MB
print('After garbage collect: ', process.memory_info().rss / 1024 ** 2, 'MB')
大多数语言,包括 Python,都没有义务在对象被销毁后将内存释放回 OS。事实上,因为 OS 分配通常是在比单个对象大得多的块中进行的,该块将包含多个对象,如果其中任何一个仍然存在,它将 不可能 到 return 它到 OS.
memory_info().rss
从 OS 的角度报告已用内存,而不是 Python 运行时的角度。
问题已被我使用的 Griddly 库的作者解决。 Python 垃圾回收无法访问克隆的环境,底层 C++ 实现中存在内存泄漏。