CPython内部结构
作者:互联网
GAE有各种各样的限制,其中一个是最大可分配内存块大小达1Mb(现在是10倍以上,但这不会改变问题).限制意味着不能在list()中放置更多的项目,因为CPython会尝试为元素指针分配连续的内存块.拥有巨大的list()可以被认为是糟糕的编程习惯,但即使程序本身没有创建庞大的结构,CPython也会在后台维护一些.
似乎CPython正在维护单个全局对象列表或其他东西.即具有许多小对象的应用程序倾向于分配越来越大的单个内存块.
第一个想法是gc,禁用它会稍微改变应用程序行为,但仍然会保留一些结构.
遇到问题的最简单的简短应用程序是:
a = b = []
number_of_lists = 8000000
for i in xrange(number_of_lists):
b.append([])
b = b[0]
任何人都可以告诉我如何防止CPython在应用程序中有很多对象时分配巨大的内部结构?
解决方法:
在32位系统上,您创建的8000000个列表中的每个列表将为列表对象本身分配20个字节,为列表元素的向量分配16个字节.所以你试图分配至少(20 16)* 8000000 = 20168000000字节,大约20 GB.这是最好的情况,如果系统malloc只分配与请求的内存完全相同的内存.
我按如下方式计算了列表对象的大小:
> PyListObject结构中的2个指针(见listobject.h)
> 1个指针和一个Py_ssize_t用于列表对象的PyObject_HEAD部分(参见object.h)
> PyObject_VAR_HEAD的一个Py_ssize_t(也在object.h中)
列表元素的向量稍微过分以避免在每次追加时调整大小 – 请参阅listobject.c中的list_resize.大小为0,4,8,16,25,35,46,58,72,88,…… ,您的单元素列表将为4个元素分配空间.
您的数据结构是一个有点病态的示例,在不使用它的情况下支付可变大小的列表对象的价格 – 您的所有列表只有一个元素.您可以通过使用元组而不是列表来避免12字节的分配,但为了进一步减少内存消耗,您将不得不使用使用较少对象的不同数据结构.由于我不知道你想要完成什么,因此很难具体化.
标签:cpython,python,data-structures,google-app-engine,internals 来源: https://codeday.me/bug/20190726/1548286.html