Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在PyPy中调试GC?_Python_Garbage Collection_Cpython_Pypy - Fatal编程技术网

Python 如何在PyPy中调试GC?

Python 如何在PyPy中调试GC?,python,garbage-collection,cpython,pypy,Python,Garbage Collection,Cpython,Pypy,最近我一直在尝试从CPython切换到pypypy,在尝试解决一个bug的同时,更准确地说是一个带有SIGSEGV信号的错误139,因此是一个分段错误,我试图通过查看GC.garbage属性列表来调查通过GC模块的垃圾收集 例如,在CPython中,我可以运行下面的代码片段,这些代码是经过修改后从中获取的,用于检查GC垃圾列表中的延迟对象: import gc gc.set_debug(gc.DEBUG_SAVEALL) print(gc.get_count()) lst = [] lst.

最近我一直在尝试从CPython切换到pypypy,在尝试解决一个bug的同时,更准确地说是一个带有SIGSEGV信号的错误139,因此是一个分段错误,我试图通过查看GC.garbage属性列表来调查通过GC模块的垃圾收集

例如,在CPython中,我可以运行下面的代码片段,这些代码是经过修改后从中获取的,用于检查GC垃圾列表中的延迟对象:

import gc

gc.set_debug(gc.DEBUG_SAVEALL)

print(gc.get_count())
lst = []
lst.append(lst)
list_id = id(lst)
del lst
gc.collect()
for item in gc.garbage:
    print(item) if list_id == id(item) else "pass"
此代码在CPython中运行良好,但在PyPy中返回以下错误:

AttributeError: module 'gc' has no attribute 'set_debug'
实际上,printdirgc为GC类返回不同的属性和方法列表,但没有列出PyPy的GC.set_debug:

# Under CPython
['DEBUG_COLLECTABLE', 'DEBUG_LEAK', 'DEBUG_SAVEALL', 'DEBUG_STATS', 'DEBUG_UNCOLLECTABLE', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'callbacks', 'collect', 'disable', 'enable', 'garbage', 'get_count', 'get_debug', 'get_objects', 'get_referents', 'get_referrers', 'get_stats', 'get_threshold', 'is_tracked', 'isenabled', 'set_debug', 'set_threshold']

# Under PyPy
['GcCollectStepStats', 'GcRef', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '_dump_rpy_heap', '_get_stats', 'collect', 'collect_step', 'disable', 'disable_finalizers', 'dump_rpy_heap', 'enable', 'enable_finalizers', 'garbage', 'get_objects', 'get_referents', 'get_referrers', 'get_rpy_memory_usage', 'get_rpy_referents', 'get_rpy_roots', 'get_rpy_type_index', 'get_stats', 'get_typeids_list', 'get_typeids_z', 'hooks', 'isenabled']
如果我理解正确,设置gc.set_debuggc.DEBUG_SAVEALL会在gc的垃圾列表中保留无法访问的对象,因此如果没有它,gc.collect将尝试释放对象的内存分配。但是我想在之前检查一下垃圾列表,因为我怀疑它触发了我试图跟踪的分段错误

尽管查阅了PyPy关于垃圾收集的文档, 在其他地方,比如说,或者,我还没有找到一种像在CPython中那样在PyPy中观察垃圾收集过程的方法。那么,有人能向我解释一下PyPy和CPython的GC之间的差异是如何影响上述测试代码的,更准确地说,在使用PyPy进行收集之前,如何能够观察GC.garbage中的挂起对象


我正在使用PyPy7.3.2运行Python 3.6.9。CPython的GCC是8.4.0,PyPy的GCC是7.3.1。

不可能完成您想要做的事情。即使在CPython上,列表gc.garbage也不会包含所有回收的对象,即使您启用了调试模式,但只包含已发现处于循环中的对象。这不太可能与任何人相关,除了周期发现逻辑本身的作者。在PyPy上,处于循环中的概念更不相关;正如您可能已经从所指向的各种链接中了解到的,PyPy的GC是完全不同的

不,没有办法检查所有正在死亡的物体。事实上,PyPy的GC是针对年轻死亡的对象进行优化的,对于所有这些对象,通常占程序中所有对象的80%-90%,那么GC的结构是这样的,以至于根本无法知道死亡的对象是什么。这80%-90%的对象占用大量回收的空间,而不是逐个回收


很可能,你从错误的角度看待你的问题。如果你能更详细地描述一下你的问题是什么,我们可以尝试提出更好的解决方案。同时,请注意,当您遇到segfault时,您可以运行pypy-X faulthandler以至少获得某种类型的回溯。

您不可能执行您试图执行的操作。即使在CPython上,列表gc.garbage也不会包含所有回收的对象,即使您启用了调试模式,但只包含已发现处于循环中的对象。这不太可能与任何人相关,除了周期发现逻辑本身的作者。在PyPy上,处于循环中的概念更不相关;正如您可能已经从所指向的各种链接中了解到的,PyPy的GC是完全不同的

不,没有办法检查所有正在死亡的物体。事实上,PyPy的GC是针对年轻死亡的对象进行优化的,对于所有这些对象,通常占程序中所有对象的80%-90%,那么GC的结构是这样的,以至于根本无法知道死亡的对象是什么。这80%-90%的对象占用大量回收的空间,而不是逐个回收

很可能,你从错误的角度看待你的问题。如果你能更详细地描述一下你的问题是什么,我们可以尝试提出更好的解决方案。同时,请注意,您可以运行pypy-X faulthandler,以便在获得segfault时至少获得某种回溯

这应该适用于CPython和PyPy

%python3-q-xfaulthandler-c导入ctypes;ctypes.string_at0 致命的Python错误:分段错误 当前线程0x00007fe10d301740最新调用优先: 文件/usr/lib/python3.8/ctypes/__init__.py,第514行,位于 文件中的第1行 分段故障堆芯 当您遇到segfault时,一些更高级的调试可能也会有帮助。您只能使用或Linux

注意,这些可以产生巨大的产量

python-m trace-trace myprogram.py strace python myprogram.py 请尝试按照以下问题的答案的建议使用运行python

这应该适用于CPython和PyPy

%python3-q-xfaulthandler-c导入ctypes;ctypes.string_at0 致命的Python错误:分段错误 当前线程0x00007fe10d301740最新调用优先: 文件/usr/lib/python3.8/ctypes/__init__.py,第514行,位于 文件中的第1行 分段故障堆芯 作为你 你遇到了一个错误,一些更高级的调试可能也会有帮助。您只能使用或Linux

注意,这些可以产生巨大的产量

python-m trace-trace myprogram.py strace python myprogram.py
重新阅读,我看到你已经建议了faulthandler!这显然是鲜为人知的,对这类案件很有帮助。可能对@Umlin有帮助,即使问题本身有点令人震惊。@Armin我明白了,谢谢你的澄清。我猜,如果大多数对象在有机会对它们进行目视检查之前就被释放了,那么进一步研究GC就没有多大意义了。还感谢您提供有关faulthandler的提示,它可能会帮助我调试segfault。如果我没有取得更大的进步,我可能会为此提出另一个问题。再读一遍,我看到你已经建议了faulthandler!这显然是鲜为人知的,对这类案件很有帮助。可能对@Umlin有帮助,即使问题本身有点令人震惊。@Armin我明白了,谢谢你的澄清。我猜,如果大多数对象在有机会对它们进行目视检查之前就被释放了,那么进一步研究GC就没有多大意义了。还感谢您提供有关faulthandler的提示,它可能会帮助我调试segfault。如果我没有取得更多的进展,我可能会为此提出另一个问题。谢谢你建议使用这些命令,它们可能会帮助我调试segfault。但我的问题是如何使用PyPy的GC进行调试,例如监视可能导致segfault的对象。回溯对于调试很有用,但它们与GC无关。感谢您建议使用这些命令,它们可能会帮助我调试segfault。但我的问题是如何使用PyPy的GC进行调试,例如监视可能导致segfault的对象。回溯对于调试很有用,但与GC无关。