但一个长期运行(最少一个星期)的daemon程序中,内存会不断增长而影响其他进程的内存分配。
最近一段时间一直苦恼于有无比较好的方法,哪怕是定时的让python释放空闲内存到系统也好。
请各位有经验的同学多支支招。
谢谢。
--
来自: python-cn`CPyUG`华蟒用户组(中文Python技术邮件列表)
发言: pyth...@googlegroups.com
退订: python-cn+...@googlegroups.com (向此发空信即退!)
详情: http://code.google.com/p/cpyug/wiki/PythonCn
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
强烈: 建议使用技巧: 如何有效地报告Bug
http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html
2011/9/26 Don <donn...@gmail.com>:
2011/9/26 Shell Xu <shell...@gmail.com>:
> 有个折中方案是新开一个进程,负责新连接,然后老进程停止accept,处理的连接数小于一定值就自杀。
> 其实在tcp编程上,可重连是一个重要考虑。把希望寄托在tcp不会中断上不是很可靠。
>
2011/9/27 机械唯物主义 : linjunhalida <linjun...@gmail.com>:
> unicorn
也就是说,如果我们运气比较差,申请了10个对象,偏偏每个对象大小差8字节。这样系统就要给我们分配10个堆,而不是刚刚好。如果你的对象粒度都比较散,那么内存开销比较大也不奇怪。
首先,fork进程去接受新连接,或类似的解决方案貌似好复杂。
另外,我写了个测试代码,地址:
http://www.cnitblog.com/donne/archive/2011/09/28/75671.html
这个在CentOS下跑出来的结果跟我们项目中发现的现象很相近。
我非常赞成Shell Xu的观点:
“
python下还有一个更坑爹的事情,也是大部分内存不释放的根本原因。在int/str等对象的模块中,有个模块级别的对象缓存链表,static
PyObject * free_list。当对象释放的时候,压根不会还到池中,而是直接在free_list中缓存。根据我的搜索,python内
部没有地方对此进行干预。
”
我觉得这个是产生这个问题的根本原因。
内存一直往上飘,用meliae却看不到异常。
我不是很同意这种看法。
如果说你们内存使用一直在稳定增加,应该不是这里的问题。
python只是缓存起来,并不是真的泄露了。如果你后面要生成对象的时候,python不会向系统申请内存,
而是直接从缓存里拿对象来用。
除非你们的应用本来就是随着时间的增加,申请的对象也越来越多,不然内存占用增长到一定量之后应该会稳定才对。
我建议你们查查是不是有哪些对象明明没用了,却还被引用着,没有释放。
--
Best Regards,
Leo Jay
感觉你的标题有点误导吧,python绝大数情况下会释放分配的内存。
至于文章中说的不分配的情况,在实际应用中比较少见。java明显占用比python要高。java的内存释放做得要比python好。
几点注释:
1. java比python更耗内存,最起码初始内存java明显占用比python要高。java的内存释放做得要比python好。
2. linux下堆栈大小是可以动态扩展的,即使初始值8M,也可以分配大于8M的对象。windows下就不清楚,难道windows下栈不能自动扩展?
3.也就是说,如果我们运气比较差,申请了10个对象,偏偏每个对象大小差8字节。这样系统就要给我们分配10个堆,而不是刚刚好。如果你的对象粒度都比较散,那么内存开销比较大也不奇怪。
“内部碎片”在所有动态分配内存方法中都存在这个问题,包括malloc。
2. linux下堆栈大小是可以动态扩展的,即使初始值8M,也可以分配大于8M的对象。windows下就不清楚,难道windows下栈不能自动扩展?linux的栈自动扩展机制不是很熟悉,windows叫做预分配机制。即预先分配1M的地址空间,然后不分配实际的内存,直到第一次使用这个内存区域,产生页面错误为止。如果使用的地址空间大于1M,那就不再捕获错误并且自动分配内存,而是抛出地址访问异常。linux的默认栈大小是可以修改的,通过ulimit。而ulimit又受到pam的限制。但是我怀疑linux的栈是否能动态扩展,因为大量扩展栈地址是会发生问题的。
2. linux下堆栈大小是可以动态扩展的,即使初始值8M,也可以分配大于8M的对象。windows下就不清楚,难道windows下栈不能自动扩展?linux的栈自动扩展机制不是很熟悉,windows叫做预分配机制。即预先分配1M的地址空间,然后不分配实际的内存,直到第一次使用这个内存区域,产生页面错误为止。如果使用的地址空间大于1M,那就不再捕获错误并且自动分配内存,而是抛出地址访问异常。linux的默认栈大小是可以修改的,通过ulimit。而ulimit又受到pam的限制。但是我怀疑linux的栈是否能动态扩展,因为大量扩展栈地址是会发生问题的。