求助python2.7 protobuff在python中创建一个对象为何要占用那么多内存

在项目中遇到一个很糟糕的问题,运行一个Python服务脚本,把服务器跑死了,以前以为开的进程过多,进程中因批量处理,导致内存和交换分区耗光引起的。后来才发现,确实是内存和交换分区无空间导致的死机,但却不是因为多进程分析引起的。
从网上看了很多资料,相关信息并不多,最后确定是由于Python对大对象内存的释放引起的。在一个对象的引用计数减为0时,与该对象对应的析构函数就会被调用,但是要特别注意的是,调用析构函数并不意味着最终一定会调用free释放内存空间,如果真是这样的话,那频繁地申请、释放内存空间会使 Python的执行效率大打折扣。
Python内存管理规则:del的时候,把list的元素释放掉,把管理元素的大对象回收到python对象缓冲池里.由此可见:python内存管理虽然很优秀,但是比较消耗内存.
一般来说,Python中大量采用了内存对象池的技术,使用这种技术可以避免频繁地申请和释放内存空间。因此在析构时,通常都是将对象占用的空间归还到内存池中。
我查看到一句话:也许能够回答自己的问题.
&这个问题就是:Python的arena从来不释放pool。这个问题为什么会引起类似于内存泄漏的现象呢。考虑这样一种情形,申请10*个16字节的小内存,这就意味着必须使用160M的内存,由于Python没有默认将前面提到的限制内存池的WITH_MEMORY_LIMITS编译符号打开,所以Python会完全使用arena来满足你的需求,这都没有问题,关键的问题在于过了一段时间,你将所有这些16字节的内存都释放了,这些内存都回到arena的控制中,似乎没有问题。但是问题恰恰就在这时出现了。因为 arena始终不会释放它维护的pool集合,所以这160M的内存始终被Python占用,如果以后程序运行中再也不需要160M如此巨大的内存,这点内存岂不是就浪费了?&
对Python内存释放的机制还不是太明白,继续学习中。
参考资料:
阅读(...) 评论()3881人阅读
Python(25)
之前跟同学讨论过numpy数组的占用空间大小问题,但是今天给忘了,又重新试验了一下,主要是利用sys模块的getsizeof函数,使用的版本是 Python3.5。记录下来,以备后忘。
一个空的numpy数组对象占用多大空间。
一个int32、int64、float32、float64数占用多大空间。
import numpy as np
import sys
ai32 = np.array([], dtype=np.int32)
bi32 = np.arange(1, dtype=np.int32)
ci32 = np.arange(5, dtype=np.int32)
ai64 = np.array([], dtype=np.int64)
bi64 = np.arange(1, dtype=np.int64)
ci64 = np.arange(5, dtype=np.int64)
af32 = np.array([], dtype=np.float32)
bf32 = np.arange(1, dtype=np.float32)
cf32 = np.arange(5, dtype=np.float32)
af64 = np.array([], dtype=np.float64)
bf64 = np.arange(1, dtype=np.float64)
cf64 = np.arange(5, dtype=np.float64)
print("size of 0 int32 number: %f" % sys.getsizeof(ai32))
print("size of 1 int32 number: %f" % sys.getsizeof(bi32))
print("size of 5 int32 numbers: %f" % sys.getsizeof(ci32), end='\n\n')
print("size of 0 int64 number: %f" % sys.getsizeof(ai64))
print("size of 1 int64 number: %f" % sys.getsizeof(bi64))
print("size of 5 int64 numbers: %f" % sys.getsizeof(ci64), end='\n\n')
print("size of 0 float32 number: %f" % sys.getsizeof(af32))
print("size of 1 float32 number: %f" % sys.getsizeof(bf32))
print("size of 5 float32 numbers: %f" % sys.getsizeof(cf32), end='\n\n')
print("size of 0 float64 number: %f" % sys.getsizeof(af64))
print("size of 1 float64 number: %f" % sys.getsizeof(bf64))
print("size of 5 float64 numbers: %f" % sys.getsizeof(cf64))
size of 0 int32 number: 96.000000
size of 1 int32 number: 100.000000
size of 5 int32 numbers: 116.000000
size of 0 int64 number: 96.000000
size of 1 int64 number: 104.000000
size of 5 int64 numbers: 136.000000
size of 0 float32 number: 96.000000
size of 1 float32 number: 100.000000
size of 5 float32 numbers: 116.000000
size of 0 float64 number: 96.000000
size of 1 float64 number: 104.000000
size of 5 float64 numbers: 136.000000
以上结果说明:
一个空的 numpy 数组,无论什么类型,都是占用 96 个字节(byte)。
一个 int32 和一个 float32 都是占用 4 个字节,而64位的都占用 8 个字节。
其他类型占用空间大小可以采用类似代码进行测试。
此外,注意 sys.getsizeof() 函数返回的是 这个对象所占用的空间大小,对于数组来说,除了数组中每个值占用空间外,数组对象还会存储数组长度、数组类型等其他信息。而如果只想要获取数组中存储的值的占用空间大小,可以使用 numpy.ndarray.nbytes ,使用 numpy.ndarray.itemsize 获取数组中每个值的占用空间大小。
ci32.nbytes
ci32.itemsize
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:219198次
积分:1969
积分:1969
排名:千里之外
原创:39篇
评论:226条
微信搜索【红叶枫啦】
(2)(2)(2)(1)(1)(6)(2)(3)(4)(5)(2)(1)(1)(1)(3)(1)(3)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'本帖子已过去太久远了,不再提供回复功能。最近碰到处理一个二十多兆的文件时内存蹭蹭的吃掉四百多兆,吓死宝宝了。
无奈毕竟接触python时间有限,还没有完整的看过python的一些基础知识,我想一个合格的pythoner应该不会碰到这个问题。当然像我这样的操作党碰到的问题映像也更深一点。最郁闷的是网上讨论这个的很有限,google的结果也是三天才找到相应的说明,我想这里很重要的一点是海量数据在存储和很低层的操作时并不会使用python,嵌入一个c片段即可。好吧这招我还不会,而且在用的库要改也是件痛苦的事,为了让项目尽早上线有个折中的方案顶上即可。在无尽的排查后发现,原来python这个东东为了让大家写的爽,在性能上事丢的不要不要的,一般的系统还看不出问题,一但不是它原声的一些对象问题就来了,原来python在实现很多功能时并不像c那样极致,而是丢失性能换来魔法般的灵活性,而这个恶魔就是字典,自定义类的属性它居然使用字典来实现的。当然python设计时假设class的使用场景并没有特定于像c的struct那么高效,好在留了一手,可以像如下添加__slots__来缩减class,使得其占用内存更紧凑接近于list,对了list比tuple要差一点,毕竟它功能更多一点,不过我觉得与其省下list这点还不如换c更实在。添加__slots__后的代码如下:
class Date:
__slots__ = ['year', 'month', 'day']
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
阅读(...) 评论()}

我要回帖

更多关于 python 解析protobuf 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信