如何手动释放python list 内存释放的内存

python手动释放 内存的问题, python explicitly free memory.
- 为程序员服务
为程序员服务
python手动释放 内存的问题, python explicitly free memory.
可以手动调用 gc.collect()
回收这种临时调用的大块内存 的最好方法还是放到函数中
用临时文件
您可能的代码
相关聚客文章
相关专栏文章1206人阅读
【C/C++ 基础】(10)
转载请标明出处:
本文出自:【的CSDN博客】
首先我们来科普一下:
什么是堆?说到堆,又忍不住说到了栈!什么是 栈?
1、什么是堆:堆是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程 初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。
2、什么是栈:栈是线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立。每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。
C语言程序编译的内存分配,堆与栈的区别:
栈是由编译器自动分配释放,存放函数的参数值、局部变量的值等。操作方式类似于数据结构中的栈。
堆一般由程序员分配释放,若不释放,程序结束时可能由OS回收。注意这里说是可能,并非一定。再强调一次,记得要释放!
栈区(stack) :
//windows下,栈内存分配2M(确定的常数),超出了限制,提示stack overflow错误
//编译器自动分配释放,主要存放函数的参数值,局部变量值等;
堆区(heap):程序员手动分配释放,操作系统80%内存
全局区或静态区:存放全局变量和静态变量;程序结束时由系统释放,分为全局初始化区和全局未初始化区;
字符常量区:常量字符串放与此,程序结束时由系统释放;
程序代码区:存放函数体的二进制代码。
void main()
char s[]="bb";
char *p3="123";
static int c=0;
p1=(char*)malloc(10);
strcpy(p1,"123");
void stackFun(){
int a[1024];
void heapFun(){
int* p = malloc(1024 * 1024 * 10 * sizeof(int));
void main(){
while (1){
Sleep(1000);
stackFun();
getchar();
创建一个数组,动态指定数组的大小(在程序运行过长中,可以随意的开辟指定大小的内存,以供使用,相当于Java中的集合)
静态内存分配,分配内存大小的是固定,问题:1.很容易超出栈内存的最大值 2.为了防止内存不够用会开辟更多的内存,容易浪费内存
动态内存分配,在程序运行过程中,动态指定需要使用的内存大小,手动释放,释放之后这些内存还可以被重新使用(活水)
函数:calloc()
分配内存空间并初始化
calloc() 函数用来动态地分配内存空间并初始化为 0,其原型为:
void* calloc (size_t num, size_t size);
calloc() 在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0。
【返回值】分配成功返回指向该内存的地址,失败则返回 NULL。
函数:malloc() 动态地分配内存空间
malloc() 函数用来动态地分配内存空间(如果你不了解动态内存分配,请查看:C语言动态内存分配及变量存储类别),其原型为:
void* malloc (size_t size);
应用在程序中代码如下:
void main(){
printf("输入数组的长度:");
scanf("%d",&len);
int* p = malloc(len * sizeof(int));
int i = 0;
for (; i & len - 1; i++){
p[i] = rand() % 100;
printf("%d,%#x\n", p[i], &p[i]);
getchar();
realloc 重新分配内存
void main(){
printf("第一次输入数组的长度:");
scanf("%d", &len);
int* p = calloc(len, sizeof(int));
int i = 0;
for (; i & i++){
p[i] = rand() % 100;
printf("%d,%#x\n", p[i], &p[i]);
printf("输入数组增加的长度:");
scanf("%d", &addLen);
int* p2 = realloc(p, sizeof(int) * (len + addLen));
if (p2 == NULL){
printf("重新分配失败,世界那么大,容不下我。。。");
新分配内存的两种情况:
//缩小,缩小的那一部分数据会丢失
//扩大,(连续的)
1.如果当前内存段后面有需要的内存空间,直接扩展这段内存空间,realloc返回原指针
2.如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据库释放掉,返回新的内存地址
3.如果申请失败,返回NULL,原来的指针仍然有效
printf("--------------------------\n");
for (; i & len + addL i++){
p2[i] = rand() % 200;
printf("%d,%#x\n", p2[i], &p2[i]);
if (p != NULL){
if (p2 != NULL){
p2 = NULL;
getchar();
内存分配的几个注意细节
1.不能多次释放;
2.释放完之后(指针仍然有值),给指针置NULL,标志释放完成;
3.内存泄露(p重新赋值之后,再free,并没有真正释放内存);
void main(){
printf("输入数组的长度:");
scanf("%d", &len);
int* p = malloc(len * sizeof(int));
int i = 0;
for (; i & i++){
p[i] = rand() % 100;
printf("%d,%#x\n", p[i], &p[i]);
if (p != NULL){
getchar();
以上就是C语言中对内存的分配与释放,常用的几个函数~
更多系列相关文章传送门:
学习理解并整理下来的笔记。
希望大家能够指点或提出宝贵意见,谢谢!一起学习。
转载请注明出处:
个人主页:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:64912次
积分:1448
积分:1448
排名:千里之外
原创:71篇
评论:38条
扫一扫下面的二维码,为你推荐最新的博文~更有惊喜等着你哦!
个人网站:
欢迎Star、Mark哦~
阅读:3332
文章:10篇
阅读:7539
阅读:18101
(1)(3)(2)(4)(8)(12)(9)(1)(4)(2)(12)(4)(6)(3)(5)(2)(1)python内存释放问题/回答/疑问 - Python - language - ITeye论坛
python内存释放问题/回答/疑问
锁定老帖子
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
等级: 初级会员
来自: 上海
发表时间:&&
最后修改:
相关知识库:
for i in range(1000 * 1000 * 10 ):
&-----&等价
l = range(1000 * 1000 * 10 )这样的内存大对象,是不会被随便释放的,直到进程退出; 我了解到一个 Boehm GC 尝试做类似的事情.GC后全部释放; 但只是Linux试验;并不是通用性解决方法;
环境:是w_xp下的虚拟机--debian下运行. 使用下面的方法: 1. &&& for i in range ( 1000000 * 10 ): ...
del i ... &&& 看能否完成你的需求? 我测试过:如果1000000,几秒就过去了. 所以我使用1000000 * 10 . 另外开一个窗口: 运行:
do ps aux | sleep 1 ; 观察mem的使用率.发现使用了47% 2.重启python运行环境. &&& def test(): ...
for i in range ( 1000000 * 10 ): ...
del i ... &&& test() 这样使用,观察mem使用率:内存上升47%,之后重复运行test(),内存只是上升20%之后就是回落到47%. 3.为什么呢?那么把这个函数定义放到一个文件里面去. "test.py" 7L, 106C
All def test():
for i in range ( 1000000 * 10 ):
del i if ( __name__ == "__main__" ):
test() 运行 python test.py 观察 mem,上升到47%--&44%--&0.2%
import time
def test():
for i in range ( 1000000 * 10 ):
if ( __name__ == "__main__" ):
while ( True ):
time.sleep( 1 )观察mem:内存维持不变!
从这点可以猜测:python不是立即释放资源的.
下面来源于:http://book.csdn.net/bookfiles/749/.shtml
在一个对象的引用计数减为0时,与该对象对应的析构函数就会被调用,但是要特别注意的是,调用析构函数并不意味着最终一定会调用free释放内存空间,如果真是这样的话,那频繁地申请、释放内存空间会使 Python的执行效率大打折扣(更何况Python已经多年背负了人们对其执行效率的不满)。一般来说,Python中大量采用了内存对象池的技术,使用这种技术可以避免频繁地申请和释放内存空间。因此在析构时,通常都是将对象占用的空间归还到内存池中。这一点在接下来对Python内建对象的实现中可以看得一清二楚。
可以解释第四次的实验结果.
查看了些资料,说这个40%的mem是能够被回收的.
这个for循环,导致的问题,确实如你所说,python不会主动释放它已经分配的过的内存.这个是它内存控制机制:减少内存分配.据说这种情况在python2.5已经解决了.但是我使用python2.5运行程序.也许是我的机器里面的python2.5可能不是最新的. 我查看到一句话:也许能够回答你的问题. "这个问题就是:Python的arena从来不释放pool。这个问题为什么会引起类似于内存泄漏的现象呢。考虑这样一种情形,申请10*个16字节的小内存,这就意味着必须使用160M的内存,由于Python没有默认将前面提到的限制内存池的WITH_MEMORY_LIMITS编译符号打开,所以Python会完全使用arena来满足你的需求,这都没有问题,关键的问题在于过了一段时间,你将所有这些16字节的内存都释放了,这些内存都回到arena的控制中,似乎没有问题。但是问题恰恰就在这时出现了。因为arena始终不会释放它维护的pool集合,所以这160M的内存始终被Python占用,如果以后程序运行中再也不需要160M如此巨大的内存, 这点内存岂不是就浪费了?" 当然,这种情形必须在大量持续申请小内存对象时才会出现,平时大家几乎不会碰到这种 情况,所以这个问题也就一直留在了Python中,但是在2004年的时候,一个叫Evan Jones的老兄不能忍受下去了。他在对一些巨大的图做某种算法操作时必须持续申请大量小块内存,这导致Python占用的内存冲上1G后就再也掉不下来。想一想,确实相当痛苦,这位老兄一番探索,终于发现问题的根源在arena这里,于是一鼓作气,搞出了一套解决方案,并在PyCon2005上做了个报告,引起了强烈的反响。但是Python的核心开发团队一直没有将这个patch并入到Python代码中,一直到2006年,才由Tim Peters(这位老兄的名头在Python社区也是响当当的,在Python的交互环境下键入import this,看到这位老兄的名号了吧,the zen of python的创造者,当然,他在Python社区的地位可不是靠这几句广告语获得的)将这个patch整理,并入到了Python代码中,加入了这个patch的Python就是我们花了这么多精力剖析的Python2.5。在Python2.4中,实际上对arena是没有区分“未使用”和“可用”两种状态的,到了Python2.5中,arena可以将自己维的pool集合释放,返回给操作系统,从而必须从“可用”状态转为“未使用”状态,这也是必须要两种状态的原因。在前面那段代码的代码[1]之后,当Python处理完pool之后,就要开始处理arena了。
个人测试代码:
-----------------------------------------------test0.py-------------------------------------
import time
def test():
for i in range ( 1000000 * 10 ):
def test_2():
#i = range ( 1000000 * 10 )
def test_3():
#i = "*" * ( 1000000 * 10 )
if ( __name__ == "__main__" ):
for i in range( 10 ):
time.sleep( 1 )
while ( True ):
time.sleep( 1 )-----------------------------------------------------test0.py--------------------------------------
运行 python test0.py
"while ( True ):
time.sleep( 1 ) "保证python不退出.
发现python的内存占用率为60%.
如何解决这个问题呢?
-----------------------------------------------test1.py-------------------------------------
#coding=utf-8import time
max_number = 1000000 * 10def test_0():
for i in range ( max_number ):
def test_1():
for i in range( 1000 ):
for i in range ( max_number / 1000 ):
if ( __name__ == "__main__" ):
#test_0()#内存使用率占40%
test_1()#内存使用率占0.2%
print "---------------------"
while ( True ):
time.sleep( 1 )
-----------------------------------------------test1.py-------------------------------------
我想问题:问题也许解决了.
这就要看你的实际需求是什么了.
我做过一个爬虫程序,如果不断往这个线程里面传递url,那么这个线程不到一会就挂了.我的改进方法:就是控制这线程能够接受的url队列长度.以及其他的优化.
如果实际情况一定非要按test1.py的test_1()函数那样运行.我想在python的上层没有什么办法帮你解决.除非
1.你修改python的内存管理机制.
2.自己写一个py与c的接口程序.具体怎么做,我还没有做过.猜想根据:python是由c实现,python与c是有接口程序的.那么有这个需求,第二种方法应该可行.
应该是这样的: def test():
tmp = range( 1000000 ) if (....):
其实这个不是循环导致的内存被python持有,而是range( n )让python分配了很多的内存.退出test(),python回收内存,但是python并不释放了,而是让pool持有内存空间.
我是找到一个方法---对方信誓旦旦说可以做到.可是好像少了东西. url:http://effbot.org/pyfaq/how-does-python-manage-memory.htm
&How does Python manage memory?& 里面好像缺少点东西:allocate_resource 我查看源码: from Carbon import Res
在代码中有一处是这样使用:
res = Res.Resource(data)
可以重新改写python源码,之后编译.可以做到.释放内存的.这个是python提供最原始的方法
不是好的办法. 以后继续关注.
本来我不准备年后再学习python源码.现在我在看它的编程方式.觉得很有意思.它的底层内存使用方式:就是内存的分配--&持有--&再利用....我觉得如果程序让python分配了太多的内存,可以针对这部分进行改进,达到不释放python持有的内存,而让python占用最低的内存使用率.
发现:python:如果这样使用:&&& l = range( 1000 * 1000 * 10 )&&& del l内存变化:60%--&47%python内存管理规则:del的时候,把list的元素释放掉,把管理元素的大对象回收到py对象缓冲池里.
由此可见:python内存管理虽然很优秀,但是比较消耗内存.
已经有了这么信息:我们应该可以按自己的愿望做点事情了:修改源码来完成我们想要的事情.
//python2.5.4-----listobject.c-----------------
static voidlist_dealloc(PyListObject *op)
/* if (num_free_lists & MAXFREELISTS && PyList_CheckExact(op)){
//printf( "free_lists[%d] = op\n", num_free_lists );
free_lists[num_free_lists++] = } else {
//printf( "free py list objects:%d\n", op-&allocated );
op-&ob_type-&tp_free((PyObject *)op);
if (num_free_lists & MAXFREELISTS && PyList_CheckExact(op)) {
if ( op-&allocated & 10000 ) {
free_lists[num_free_lists++] =
printf( "free py list objects: op-&allocated = %d & 10000 MAXFREELISTS = %d\n", op-&allocated,MAXFREELISTS );
op-&ob_type-&tp_free((PyObject *)op);
printf( "free py list objects: op-&allocated = %d MAXFREELISTS = %d \n", op-&allocated,MAXFREELISTS );
op-&ob_type-&tp_free((PyObject *)op);
编译--&安装.
打印信息告诉我们是释放了list大对象.但是查看py的内存持有量:发现并没有变化...
是什么原因呢?
---------------------------------------------decompose_while.py---------------------------------------------------------
#coding=utf-8
i = 0j = 0k = 0c = 0l = []while i & 10:
while j & 1000:
while k & 1000:
l.append( c )print "l.len = ",len( l )import timewhile True:
time.sleep( 2 )
---------------------------------------------decompose_while.py---------------------------------------------------------
[list_div]root python decompose_while.py l.len =
.....程序sleep...
我一直怀疑一个对象怎么能够占用60%的内存空间呢?而且,我实验了很多种情况,在一个py虚拟机下不断: create list--&del list --&create list .... 也发现内存维持在60% &--& 47%之间变化.
下面我们计算下:
一个1000 * 1000 * 10大的list对象,它至少应该占有多大的内存空间:
1000 * 1000 * 10 * ( sizeof(int) ) = 40,000,000
40,000,000 /
38.15 / 256 = 0.149 % (注:我是在虚拟机里运行,分配给虚拟机是256M的内存空间,不知用这个算是否对?请指正!)
(list对象应该还有一些其他变量需要分配一些内存空间吧,这里就没有做计算了)
就是说:这个list对象应该占用系统内存的0.2%左右.
那么40%可能是在创建list的时候转换到py的缓冲池里去了.
py的内存分配规则:....可以说明这个问题.各位可以去找找看,我也会在后续补充进来.(不知道这个猜测对不对!?)
跳转论坛:移动开发技术
Web前端技术
Java企业应用
编程语言技术1682人阅读
其他(11)
在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好。但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了。
Linux系统的缓存机制是相当先进的,他会针对dentry(用于VFS,加速文件路径名到inode的转换)、Buffer Cache(针对磁盘块的读写)和Page Cache(针对文件inode的读写)进行缓存操作。但是在进行了大量文件操作之后,缓存会把内存资源基本用光。但实际上我们文件操作已经完成,这部分 缓存已经用不到了。这个时候,我们难道只能眼睁睁的看着缓存把内存空间占据掉么?
所以,我们还是有必要来手动进行Linux下释放内存的操作,其实也就是释放缓存的操作了。
要达到释放缓存的目的,我们首先需要了解下关键的配置文件/proc/sys/vm/drop_caches。这个文件中记录了缓存释放的参数,默认值为0,也就是不释放缓存。他的值可以为0~3之间的任意数字,代表着不同的含义:
0 – 不释放
1 – 释放页缓存
2 – 释放dentries和inodes
3 – 释放所有缓存
知道了参数后,我们就可以根据我们的需要,使用下面的指令来进行操作。
首先我们需要使用sync指令,将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。否则在释放缓存的过程中,可能会丢失未保存的文件。
接下来,我们需要将需要的参数写进/proc/sys/vm/drop_caches文件中,比如我们需要释放所有缓存,就输入下面的命令:
#echo 3 & /proc/sys/vm/drop_caches
此指令输入后会立即生效,可以查询现在的可用内存明显的变多了。
要查询当前缓存释放的参数,可以输入下面的指令:
#cat /proc/sys/vm/drop_caches
在Linux下查看内存我们一般用command free
[root@nonamelinux ~]# free
total used free shared buffers cached
Mem: 116 80 155468
-/+ buffers/cache: 656
下面是对这些数值的解释:
第二行(mem):
total:总计物理内存的大小。
used:已使用多大。
free:可用有多少。
Shared:多个进程共享的内存总额。
Buffers/cached:磁盘缓存的大小。
第三行(-/+ buffers/cached):
used:已使用多大。
free:可用有多少。
第四行就不多解释了。
第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。
这 两个的区别在于使用的角度来看,第一行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是8908KB,已用内存是377116KB,其中包括,内核(OS)使用+Application(X, oracle,etc)使用的+buffers+cached.
第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。
所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached.
8+2468
接下来解释什么时候内存会被交换,以及按什么方交换。
当可用内存少于额定值的时候,就会开会进行交换.
如何看额定值(RHEL4.0):
#cat /proc/meminfo
交换将通过三个途径来减少系统中使用的物理页面的个数: 
1.减少缓冲与页面cache的大小,
2.将系统V类型的内存页面交换出去, 
3.换出或者丢弃页面。(Application 占用的内存页,也就是物理内存不足)。
事实上,少量地使用swap是不是影响到系统性能的。
下面是buffers与cached的区别。
buffers是指用来给块设备做的缓冲大小,他只记录文件系统的metadata以及 tracking in-flight pages.
cached是用来给文件做缓冲。
那就是说:buffers是用来存储,目录里面有什么内容,权限等等。
而cached直接用来记忆我们打开的文件,如果你想知道他是不是真的生效,你可以试一下,先后执行两次命令#man X ,你就可以明显的感觉到第二次的开打的速度快很多。
实验:在一台没有什么应用的机器上做会看得比较明显。记得实验只能做一次,如果想多做请换一个文件名。
你可以先后比较一下free后显示buffers的大小。
另一个实验:
你比较一下两个的大小,当然这个buffers随时都在增加,但你有ls过的话,增加的速度会变得快,这个就是buffers/chached的区别。&
因为Linux将你暂时不使用的内存作为文件和数据缓存,以提高系统性能,当你需要这些内存时,系统会自动释放(不像windows那样,即使你有很多空闲内存,他也要访问一下磁盘中的pagefiles) &&
使用free命令 &&
将used的值减去 & buffer和cache的值就是你当前真实内存使用
再来说一下释放这种文件缓存的方法
Shell代码 &
[root@server ~]# sync &
[root@server ~]# echo 3 & /proc/sys/vm/drop_caches &
[root@server ~]# free -m &&
这回再用free命令查看一下内存情况。
设置了这个参数后不是一直起作用,或者是以后就不缓存了。而是只有再执行清除缓存命令的时候才生效。清除完缓存后如果继续进行文件的读取等操作,还会产生缓存。
想再次释放缓存还得执行上面的3个命令。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:212155次
积分:2327
积分:2327
排名:第13531名
转载:158篇
(2)(1)(21)(2)(20)(23)(6)(15)(28)(26)(18)(8)

我要回帖

更多关于 python 内存释放 的文章

 

随机推荐