Python C API 引用计数器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python C API 引用计数器相关的知识,希望对你有一定的参考价值。
简介
Python的内存管理是通过对象的引用计数器来实现的,对象的创建会将引用计数器加1,被引用一次则引用计数器就会加1,反之解除引用时,则引用计数器就会减1,当Python对象的引用计数器为0的时候,则这个对象就会被回收和释放。
这种内存管理的方式是有一定的弊端的,一是它需要额外的空间维护引用计数,二是它不能解决对象的“循环引用”的问题,因此,也有很多语言比如Java并没有采用该算法做来垃圾的回收机制。
Python代码实例
import sys
def test_refcount(a):
print("func a refcount: {}".format(sys.getrefcount(a)))
if __name__ == ‘__main__‘:
// 直接创建Python对象
a = 189987319
print("a refcount: {}".format(sys.getrefcount(a)))
// 调用一次Python对象a,则引用计数器加1
b = a
print("b, a refcount: {}".format(sys.getrefcount(a)))
// 存入列表,字段,或者元组中,引用计数器都会加1
c = [a]
print("c, a refcount: {}".format(sys.getrefcount(a)))
// 使用函数调用的时候,传参的时候引用计数器加1,调用的时候引用计数器也会加1,因此是加2
test_refcount(a)
结果:
a refcount: 1
b, a refcount: 2
c, a refcount: 3
func a refcount: 5
Python C API中管理及释放Python对象
void Py_INCREF(PyObject *o) Python对象引用计数器加1,该对象不能为NULL,否则会报错
void Py_XINCREF(PyObject *o) Python对象引用计数器加1,该对象可以为NULL,但是引用计数器未生效
void Py_DECREF(PyObject *o) Python对象的引用计数器减1,该对象不能为NULL,否则会报错
void Py_XDECREF(PyObject *o) Python对象引用计数器减1,该对象可以为NULL,但是引用计数器未生效
void Py_CLEAR(PyObject *o) 直接将Python应用计数器清0
C代码实例
头文件
//
// Created by lanyulei on 18-9-9.
//
#ifndef PRINT_DEMO1_PYREFCOUNT_H
#define PRINT_DEMO1_PYREFCOUNT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Python.h>
void pyRefCount();
#endif //PRINT_DEMO1_PYREFCOUNT_H
源文件
//
// Created by lanyulei on 18-9-9.
//
#include "pyRefCount.h"
// Python对象的保留及释放
void pyRefCount(){
PyObject* py_ival = Py_BuildValue("i", 56486); // 创建对象
printf("Py_BuildValue: py_ival refcount: %ld
", Py_REFCNT(py_ival)); // 打印Python对象的引用计数器
Py_XINCREF(py_ival); // Python对象的引用计数器加1
printf("Py_BuildValue: py_ival refcount: %ld
", Py_REFCNT(py_ival)); // 打印Python对象的引用计数器
Py_XDECREF(py_ival); // Python对象的引用计数器减1
printf("Py_BuildValue: py_ival refcount: %ld
", Py_REFCNT(py_ival)); // 打印Python对象的引用计数器
Py_CLEAR(py_ival); // Python对象的引用计数器清0
printf("Py_BuildValue: py_ival refcount: %ld
", Py_REFCNT(py_ival)); // 打印Python对象的引用计数器
}
main.cpp
#include "pyRefCount.h"
int main() {
// 初始化Python虚拟机
Py_Initialize();
// 判断Python虚拟机是否成功
if (Py_IsInitialized() == 0){
printf("fal to initialize Python
");
return -1;
}
printf("server start
");
pyRefCount();
// 退出Python虚拟机
Py_Finalize();
return 0;
}
以上是关于Python C API 引用计数器的主要内容,如果未能解决你的问题,请参考以下文章