You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对上一次Py_Initialize前创建的对象调用Py_DecRef是否安全?

结论

就算满足你假设的「所有参与模块都正确处理Py_Finalize」的前提,你描述的跨Py_Finalize/Py_Initialize周期调用Py_DecRef释放旧对象的操作仍然不符合Python C API设计规范,是不安全的,你遇到的崩溃属于预期行为。

核心原因
  • Py_Finalize执行时会销毁当前Python运行时实例的所有资源:包括所有已分配的PyObject对象、GC结构、类型定义、内置对象等,无论你是否手动调用Py_IncRef增加过引用计数,这些对象占用的内存都会被全部释放,你保留的对象指针在Py_Finalize完成后就已经是野指针。
  • 后续调用Py_Initialize会创建完全独立的全新Python运行时实例,和之前销毁的运行时没有任何关联,旧的对象指针对新运行时没有任何意义,对野指针执行Py_DecRef会操作无效内存,破坏新运行时的GC链表结构,自然会触发gcmodule.c里的validate_list断言失败。
适配你场景的解决方案

你的场景是.NET GC托管Python对象的生命周期,需要做如下调整:

  • 每次调用Py_Finalize之前,必须主动遍历所有托管侧持有Python对象引用的资源,全部提前调用Py_DecRef释放,同时将这些引用标记为永久失效,避免后续.NET GC触发回收时再对无效指针执行释放操作。
  • 如果确实需要跨运行时周期保留数据,不能直接保留PyObject指针,要提前将数据序列化为原生类型(比如字符串、字节数组、原生结构体等),下一次运行时初始化完成后再重新反序列化为Python对象使用。

内容的提问来源于stack exchange,提问作者LOST

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:45:08