﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-&lt;script language="javascript" src="http://www.shi-ci.com/embeded.do"&gt;&lt;/script&gt;-随笔分类-Python</title><link>http://www.blogjava.net/yglwxl/category/39566.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 30 Nov 2009 11:11:11 GMT</lastBuildDate><pubDate>Mon, 30 Nov 2009 11:11:11 GMT</pubDate><ttl>60</ttl><item><title>How does Python manage memory?(http://docs.python.org/3.1/faq/design.html)</title><link>http://www.blogjava.net/yglwxl/archive/2009/11/30/304232.html</link><dc:creator>九宝</dc:creator><author>九宝</author><pubDate>Mon, 30 Nov 2009 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/yglwxl/archive/2009/11/30/304232.html</guid><wfw:comment>http://www.blogjava.net/yglwxl/comments/304232.html</wfw:comment><comments>http://www.blogjava.net/yglwxl/archive/2009/11/30/304232.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yglwxl/comments/commentRss/304232.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yglwxl/services/trackbacks/304232.html</trackback:ping><description><![CDATA[<p>The details of Python memory management depend on the implementation. The standard C implementation of Python <span style="color: #ff0000">uses reference counting to detect inaccessible objects</span>, and <span style="color: #ff0000">another mechanism to collect reference cycles, periodically executing a cycle detection algorithm which looks for inaccessible cycles and deletes the objects involved. </span>The <a class="reference external" title="Interface to the cycle-detecting garbage collector." href="http://docs.python.org/3.1/library/gc.html#module-gc"><tt class="xref docutils literal"><span class="pre">gc</span></tt></a> module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector&#8217;s parameters.</p>
<p>Jython relies on the Java runtime so the JVM&#8217;s garbage collector is used. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation.</p>
<p>Sometimes objects get stuck in tracebacks temporarily and hence are not deallocated when you might expect. Clear the tracebacks with:</p>
<div class="highlight-python3">
<div class="highlight">
<pre><span class="kn">import</span> <span class="nn">sys</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exc_clear</span><span class="p">()</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exc_traceback</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">last_traceback</span> <span class="o">=</span> <span class="k">None</span>
</pre>
</div>
</div>
<p>Tracebacks are used for reporting errors, implementing debuggers and related things. They contain a portion of the program state extracted during the handling of an exception (usually the most recent exception).</p>
<p>In the absence of circularities and tracebacks, Python programs need not explicitly manage memory.</p>
<p>Why doesn&#8217;t Python use a more traditional garbage collection scheme? For one thing, this is not a C standard feature and hence it&#8217;s not portable. (Yes, we know about the Boehm GC library. It has bits of assembler code for <em>most</em> common platforms, not for all of them, and although it is mostly transparent, it isn&#8217;t completely transparent; patches are required to get Python to work with it.)</p>
<p>Traditional GC also becomes a problem when Python is embedded into other applications. While in a standalone Python it&#8217;s fine to replace the standard malloc() and free() with versions provided by the GC library, an application embedding Python may want to have its <em>own</em> substitute for malloc() and free(), and may not want Python&#8217;s. Right now, Python works with anything that implements malloc() and free() properly.</p>
<p>In Jython, the following code (which is fine in CPython) will probably run out of file descriptors long before it runs out of memory:</p>
<div class="highlight-python3">
<div class="highlight">
<pre><span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">very</span> <span class="n">long</span> <span class="nb">list</span> <span class="n">of</span> <span class="n">files</span><span class="o">&gt;</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</pre>
</div>
</div>
<p>Using the current reference counting and destructor scheme, each new assignment to f closes the previous file. Using GC, this is not guaranteed. If you want to write code that will work with any Python implementation, you should explicitly close the file; this will work regardless of GC:</p>
<div class="highlight-python3">
<div class="highlight">
<pre><span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">very</span> <span class="n">long</span> <span class="nb">list</span> <span class="n">of</span> <span class="n">files</span><span class="o">&gt;</span><span class="p">:</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre>
</div>
</div>
<img src ="http://www.blogjava.net/yglwxl/aggbug/304232.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yglwxl/" target="_blank">九宝</a> 2009-11-30 11:01 <a href="http://www.blogjava.net/yglwxl/archive/2009/11/30/304232.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python 循环引用导致内存泄漏的内存管理TEST ref from：http://meizhini.javaeye.com/blog/249716</title><link>http://www.blogjava.net/yglwxl/archive/2009/11/30/304229.html</link><dc:creator>九宝</dc:creator><author>九宝</author><pubDate>Mon, 30 Nov 2009 02:47:00 GMT</pubDate><guid>http://www.blogjava.net/yglwxl/archive/2009/11/30/304229.html</guid><wfw:comment>http://www.blogjava.net/yglwxl/comments/304229.html</wfw:comment><comments>http://www.blogjava.net/yglwxl/archive/2009/11/30/304229.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yglwxl/comments/commentRss/304229.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yglwxl/services/trackbacks/304229.html</trackback:ping><description><![CDATA[&nbsp; 在 Python 中，为了解决内存泄漏问题，采用了对象引用计数，并基于引用计数实现自动垃圾回收。<br />
&nbsp;&nbsp;&nbsp; 因为 Python 有了自动垃圾回收功能，不少初学者就认为自己从此过上了好日子，不必再受内存泄漏的骚扰了。但如果查看一下 Python 文档对 __del__() 函数的描述，就知道好日子里也是有阴云的。下面摘抄一点文档内容：<br />
&nbsp;&nbsp;&nbsp; Some common situations that may prevent the reference count of an object from going to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object on the stack frame of a function that caught an exception (the traceback stored in sys.exc_traceback keeps the stack frame alive); or a reference to the object on the stack frame that raised an unhandled exception in interactive mode (the traceback stored in sys.last_traceback keeps the stack frame alive).<br />
&nbsp;&nbsp;&nbsp; 可见，有 __del__() 函数的对象间的循环引用是导致内存泄漏的主凶。特别说明：对没有 __del__() 函数的 Python 对象间的循环引用，是可以被自动垃圾回收掉的。<br />
<br />
<br />
有 __del__() 函数的对象间的循环引用是导致内存泄漏的主凶。特别说明：对没有 __del__() 函数的 Python 对象间的循环引用，是可以被自动垃圾回收掉的。所以，没什么事，千万不要轻易启用__del__操作。<br />
如何知道一个对象是否内存泄漏了呢？<br />
&nbsp;&nbsp;&nbsp; 方法一、当你认为一个对象应该被销毁时（即引用计数为 0），可以通过 sys.getrefcount(obj) 来获取对象的引用计数，并根据返回值是否为 0 来判断是否内存泄漏。如果返回的引用计数不为 0，说明在此刻对象 obj 是不能被垃圾回收器回收掉的。<br />
&nbsp;&nbsp;&nbsp; 方法二、也可以通过 Python 扩展模块 gc 来查看不能回收的对象的详细信息。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; 首先，来看一段正常的测试代码：<br />
<br />
#--------------- code begin --------------<br />
<br />
# -*- coding: utf-8 -*-<br />
<br />
import gc<br />
import sys<br />
<br />
class <span class="hilite1">CGcLeak</span>(object):<br />
&nbsp;&nbsp;&nbsp; def __init__(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._text = '#'*10<br />
<br />
&nbsp;&nbsp;&nbsp; def __del__(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass<br />
<br />
def make_circle_ref():<br />
&nbsp;&nbsp;&nbsp; _gcleak = <span class="hilite1">CGcLeak</span>()<br />
#&nbsp;&nbsp; _gcleak._self = _gcleak # test_code_1<br />
&nbsp;&nbsp;&nbsp; print '_gcleak ref count0:%d' % sys.getrefcount(_gcleak)<br />
&nbsp;&nbsp;&nbsp; del _gcleak<br />
&nbsp;&nbsp;&nbsp; try:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print '_gcleak ref count1:%d' % sys.getrefcount(_gcleak)<br />
&nbsp;&nbsp;&nbsp; except UnboundLocalError:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print '_gcleak is invalid!'<br />
<br />
def test_gcleak():<br />
&nbsp;&nbsp;&nbsp; # Enable automatic garbage collection.<br />
&nbsp;&nbsp;&nbsp; gc.enable()<br />
&nbsp;&nbsp;&nbsp; # Set the garbage collection debugging flags.<br />
&nbsp;&nbsp;&nbsp; gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | \<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS)<br />
<br />
&nbsp;&nbsp;&nbsp; print 'begin leak test...'<br />
&nbsp;&nbsp;&nbsp; make_circle_ref()<br />
<br />
&nbsp;&nbsp;&nbsp; print 'begin collect...'<br />
&nbsp;&nbsp;&nbsp; _unreachable = gc.collect()<br />
&nbsp;&nbsp;&nbsp; print 'unreachable object num:%d' % _unreachable<br />
&nbsp;&nbsp;&nbsp; print 'garbage object num:%d' % len(gc.garbage)<br />
<br />
if __name__ == '__main__':<br />
&nbsp;&nbsp;&nbsp; test_gcleak()<br />
<br />
#--------------- code end ----------------<br />
<br />
&nbsp;&nbsp;&nbsp; 在 test_gcleak() 中，设置垃圾回收器调试标志后，再用 collect() 进行垃圾回收，最后打印出该次垃圾回收发现的不可达的垃圾对象数和整个解释器中的垃圾对象数。<br />
<br />
&nbsp;&nbsp;&nbsp; gc.garbage 是一个 list 对象，列表项是垃圾收集器发现的不可达（即是垃圾对象）、但又不能释放（即不能回收）的对象。文档描述为：A list of objects which the collector found to be unreachable but could not be freed (uncollectable objects).<br />
&nbsp;&nbsp;&nbsp; 通常，gc.garbage 中的对象是引用环中的对象。因为 Python 不知道按照什么样的安全次序来调用环中对象的 __del__() 函数，导致对象始终存活在 gc.garbage 中，造成内存泄漏。如果知道一个安全的次序，那么就打破引用环，再执行 del gc.garbage[:] ，以清空垃圾对象列表。<br />
<br />
&nbsp;&nbsp;&nbsp; 上段代码输出为（#后字符串为笔者所加注释）：<br />
#-----------------------------------------<br />
begin leak test...<br />
# 变量 _gcleak 的引用计数为 2.<br />
_gcleak ref count0:2<br />
# _gcleak 变为不可达(unreachable)的非法变量.<br />
_gcleak is invalid!<br />
# 开始垃圾回收<br />
begin collect...<br />
# 本次垃圾回收发现的不可达的垃圾对象数为 0.<br />
unreachable object num:0<br />
# 整个解释器中的垃圾对象数为 0.<br />
garbage object num:0<br />
#-----------------------------------------<br />
&nbsp;&nbsp;&nbsp; 可见 _gcleak 对象的引用计数是正确的，也没有任何对象发生内存泄漏。<br />
<br />
&nbsp;&nbsp;&nbsp; 如果不注释掉 make_circle_ref() 中的 test_code_1 语句：<br />
&nbsp;&nbsp;&nbsp; _gcleak._self = _gcleak<br />
也就是让 _gcleak 形成一个自己对自己的循环引用。再运行上述代码，输出结果就变成：<br />
#-----------------------------------------<br />
begin leak test...<br />
_gcleak ref count0:3<br />
_gcleak is invalid!<br />
begin collect...<br />
# 发现可以回收的垃圾对象: 地址为 012AA090，类型为 <span class="hilite1">CGcLeak</span>.<br />
gc: uncollectable &lt;<span class="hilite1">CGcLeak</span> 012AA090&gt;<br />
gc: uncollectable &lt;dict 012AC1E0&gt;<br />
unreachable object num:2<br />
#!! 不能回收的垃圾对象数为 1，导致内存泄漏！<br />
garbage object num:1<br />
#-----------------------------------------<br />
&nbsp;&nbsp;&nbsp; 可见 &lt;<span class="hilite1">CGcLeak</span> 012AA090&gt; 对象发生了内存泄漏！！而多出的 dict 垃圾就是泄漏的 _gcleak 对象的字典，打印出字典信息为:<br />
{'_self': &lt;__main__.<span class="hilite1">CGcLeak</span> object at 0x012AA090&gt;, '_text': '##########'}<br />
<br />
&nbsp;&nbsp;&nbsp; 除了对自己的循环引用，多个对象间的循环引用也会导致内存泄漏。简单举例如下：<br />
<br />
#--------------- code begin --------------<br />
<br />
class CGcLeakA(object):<br />
&nbsp;&nbsp;&nbsp; def __init__(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._text = '#'*10<br />
<br />
&nbsp;&nbsp;&nbsp; def __del__(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass<br />
<br />
class CGcLeakB(object):<br />
&nbsp;&nbsp;&nbsp; def __init__(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._text = '*'*10<br />
<br />
&nbsp;&nbsp;&nbsp; def __del__(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass<br />
<br />
def make_circle_ref():<br />
&nbsp;&nbsp;&nbsp; _a = CGcLeakA()<br />
&nbsp;&nbsp;&nbsp; _b = CGcLeakB()<br />
&nbsp;&nbsp;&nbsp; _a._b = _b&nbsp; # test_code_2<br />
&nbsp;&nbsp;&nbsp; _b._a = _a&nbsp; # test_code_3<br />
&nbsp;&nbsp;&nbsp; print 'ref count0:a=%d b=%d' % \<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (sys.getrefcount(_a), sys.getrefcount(_b))<br />
#&nbsp;&nbsp; _b._a = None&nbsp;&nbsp;&nbsp; # test_code_4<br />
&nbsp;&nbsp;&nbsp; del _a<br />
&nbsp;&nbsp;&nbsp; del _b<br />
&nbsp;&nbsp;&nbsp; try:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'ref count1:a=%d' % sys.getrefcount(_a)<br />
&nbsp;&nbsp;&nbsp; except UnboundLocalError:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print '_a is invalid!'<br />
&nbsp;&nbsp;&nbsp; try:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'ref count2:b=%d' % sys.getrefcount(_b)<br />
&nbsp;&nbsp;&nbsp; except UnboundLocalError:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print '_b is invalid!'<br />
<br />
#--------------- code end ----------------<br />
<br />
&nbsp;&nbsp;&nbsp; 这次测试后输出结果为：<br />
#-----------------------------------------<br />
begin leak test...<br />
ref count0:a=3 b=3<br />
_a is invalid!<br />
_b is invalid!<br />
begin collect...<br />
gc: uncollectable &lt;CGcLeakA 012AA110&gt;<br />
gc: uncollectable &lt;CGcLeakB 012AA0B0&gt;<br />
gc: uncollectable &lt;dict 012AC1E0&gt;<br />
gc: uncollectable &lt;dict 012AC0C0&gt;<br />
unreachable object num:4<br />
garbage object num:2<br />
#-----------------------------------------<br />
可见 _a,_b 对象都发生了内存泄漏。因为二者是循环引用，垃圾回收器不知道该如何回收，也就是不知道该首先调用那个对象的 __del__() 函数。<br />
<br />
&nbsp;&nbsp;&nbsp; 采用以下任一方法，打破环状引用，就可以避免内存泄漏：<br />
[1] 注释掉 make_circle_ref() 中的 test_code_2 语句；<br />
[2] 注释掉 make_circle_ref() 中的 test_code_3 语句；<br />
[3] 取消对 make_circle_ref() 中的 test_code_4 语句的注释。<br />
相应输出结果变为：<br />
#-----------------------------------------<br />
begin leak test...<br />
ref count0:a=2 b=3&nbsp; # 注：此处输出结果视情况变化.<br />
_a is invalid!<br />
_b is invalid!<br />
begin collect...<br />
unreachable object num:0<br />
garbage object num:0<br />
#-----------------------------------------<br />
<br />
<br />
&nbsp;&nbsp;&nbsp; 结论：Python 的 gc 有比较强的功能，比如设置 gc.set_debug(gc.DEBUG_LEAK) 就可以进行循环引用导致的内存泄露的检查。如果在开发时进行内存泄露检查；在发布时能够确保不会内存泄露，那么就可以延长 Python 的垃圾回收时间间隔、甚至主动关闭垃圾回收机制，从而提高运行效率。<br />
<img src ="http://www.blogjava.net/yglwxl/aggbug/304229.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yglwxl/" target="_blank">九宝</a> 2009-11-30 10:47 <a href="http://www.blogjava.net/yglwxl/archive/2009/11/30/304229.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Come from  : Python源码剖析——Python的内存管理机制</title><link>http://www.blogjava.net/yglwxl/archive/2009/11/30/304225.html</link><dc:creator>九宝</dc:creator><author>九宝</author><pubDate>Mon, 30 Nov 2009 02:35:00 GMT</pubDate><guid>http://www.blogjava.net/yglwxl/archive/2009/11/30/304225.html</guid><wfw:comment>http://www.blogjava.net/yglwxl/comments/304225.html</wfw:comment><comments>http://www.blogjava.net/yglwxl/archive/2009/11/30/304225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yglwxl/comments/commentRss/304225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yglwxl/services/trackbacks/304225.html</trackback:ping><description><![CDATA[1.小块空间的内存池<br />
在Python中，许多时候申请的内存都是小块的内存，这些小块内存在申请后，很快又会<br />
被释放，由于这些内存的申请并不是为了创建对象，所以并没有对象一级的内存池机制。这就<br />
意味着Python在运行期间会大量地执行malloc和free的操作，频繁地在用户态和核心态之间<br />
进行切换，这将严重影响Python的执行效率。为了加速Python的执行效率，Python引入了一<br />
个内存池机制，用于管理对小块内存的申请和释放。这也就是之前提到的Pymalloc机制.<br />
<br />
2.在Python2.5中，Python内部默认的小块内存与大块内存的分界点定在256个字节，这个<br />
分界点由前面我们看到的名为SMALL_REQUEST_THRESHOLD的符号控制。也就是说，当申<br />
请的内存小于256字节时，PyObject_Malloc会在内存池中申请内存；当申请的内存大于256<br />
字节时，PyObject_Malloc的行为将蜕化为malloc的行为。当然，通过修改Python源代码，我<br />
们可以改变这个默认值，从而改变Python的默认内存管理行为。 <br />
<br />
3.在一个对象的引用计数减为0时，与该对象对应的析构函数就会被调用，但是要特别注意的是，调用析构函数并不意味着最终一定会调用free释放内存空间，如果真是这样的话，那频繁地申请、释放内存空间会使 <span class="hilite1">Python</span>的执行效率大打折扣（更何况<span class="hilite1">Python</span>已经多年背负了人们对其执行效率的不满）。一般来说，<span class="hilite1">Python</span>中大量采用了内存对象池的技术，使用这种技术可以避免频繁地申请和释放内存空间。因此在析构时，通常都是将对象占用的空间归还到内存池中。<br />
"这个问题就是:<span class="hilite1">Python</span>的arena从来不释放pool。这个问题为什么会引起类似于内存泄漏的现象呢。考虑这样一种情形，申请10*1024*1024个16字节的小内存，这就意味着必须使用160M的内存，由于<span class="hilite1">Python</span>没有默认将前面提到的限制内存池的WITH_MEMORY_LIMITS编译符号打开，所以<span class="hilite1">Python</span>会完全使用arena来满足你的需求，这都没有问题，关键的问题在于过了一段时间，你将所有这些16字节的内存都释放了，这些内存都回到arena的控制中，似乎没有问题。但是问题恰恰就在这时出现了。因为arena始终不会释放它维护的pool集合，所以这160M的内存始终被<span class="hilite1">Python</span>占用，如果以后程序运行中再也不需要160M如此巨大的内存， <br />
这点内存岂不是就浪费了？" <br />
<span class="hilite1">python</span>内存管理规则:<br />
del的时候,把list的元素释放掉,把管理元素的大对象回收到py对象缓冲池里. <br />
<img src ="http://www.blogjava.net/yglwxl/aggbug/304225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yglwxl/" target="_blank">九宝</a> 2009-11-30 10:35 <a href="http://www.blogjava.net/yglwxl/archive/2009/11/30/304225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python 小块空间内存管理TEST ref from： http://www.javaeye.com/topic/309753</title><link>http://www.blogjava.net/yglwxl/archive/2009/11/27/303916.html</link><dc:creator>九宝</dc:creator><author>九宝</author><pubDate>Fri, 27 Nov 2009 08:54:00 GMT</pubDate><guid>http://www.blogjava.net/yglwxl/archive/2009/11/27/303916.html</guid><wfw:comment>http://www.blogjava.net/yglwxl/comments/303916.html</wfw:comment><comments>http://www.blogjava.net/yglwxl/archive/2009/11/27/303916.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/yglwxl/comments/commentRss/303916.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yglwxl/services/trackbacks/303916.html</trackback:ping><description><![CDATA[mport time
<p>def test():<br />
&nbsp;&nbsp; for i in range ( 1000000 * 10 ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del i</p>
<p>if ( __name__ == "__main__" ):<br />
&nbsp;&nbsp;&nbsp; test()<br />
&nbsp;&nbsp;&nbsp; while ( True ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep( 1 )<br />
观察mem:内存维持不变!&nbsp;</p>
<p>从这点可以猜测:python不是立即释放资源的.<br />
<br />
</p>
<p>个人测试代码:<br />
-----------------------------------------------test0.py-------------------------------------</p>
<p>import time</p>
<p>def test():<br />
&nbsp;&nbsp;&nbsp; for i in range ( 1000000 * 10 ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del i</p>
<p><br />
def test_2():<br />
&nbsp;&nbsp;&nbsp; #i = range ( 1000000 * 10 )<br />
&nbsp;&nbsp;&nbsp; #del i<br />
&nbsp;&nbsp;&nbsp; pass</p>
<p>def test_3():<br />
&nbsp;&nbsp;&nbsp; #i = "*" * ( 1000000 * 10 )<br />
&nbsp;&nbsp;&nbsp; #del i<br />
&nbsp;&nbsp;&nbsp; pass</p>
<p><br />
if ( __name__ == "__main__" ):<br />
&nbsp;&nbsp;&nbsp; for i in range( 10 ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test_2()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test_3()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep( 1 )<br />
&nbsp;&nbsp;&nbsp; while ( True ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep( 1 )<br />
-----------------------------------------------------test0.py--------------------------------------&nbsp;</p>
<p>运行 python test0.py</p>
<p>"while ( True ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep( 1 )<br />
&nbsp;"<br />
保证python不退出.</p>
<p>发现python的内存占用率为60%.</p>
<p>&nbsp;</p>
<p>如何解决这个问题呢?看下面的:</p>
<p>-----------------------------------------------test1.py-------------------------------------</p>
<p>#coding=utf-8<br />
import time</p>
<p>max_number = 1000000 * 10<br />
def test_0():<br />
&nbsp;&nbsp;&nbsp; for i in range ( max_number ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del i</p>
<p>def test_1():<br />
&nbsp;&nbsp;&nbsp; for i in range( 1000 ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for i in range ( max_number / 1000 ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del i</p>
<p>if ( __name__ == "__main__" ):<br />
&nbsp;&nbsp;&nbsp; #test_0()#内存使用率占40%<br />
&nbsp;&nbsp;&nbsp; test_1()#内存使用率占0.2%<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; print "---------------------"<br />
&nbsp;&nbsp;&nbsp; while ( True ):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time.sleep( 1 )</p>
<p>-----------------------------------------------test1.py-------------------------------------</p>
<p>&nbsp;我想问题:问题也许解决了.</p>
<p>这就要看你的实际需求是什么了.</p>
<p>例如:</p>
<p>我做过一个爬虫程序,如果不断往这个线程里面传递url,那么这个线程不到一会就挂了.我的改进方法:就是控制这线程能够接受的url队列长度.以及其他的优化.<br />
&nbsp;其实这个不是循环导致的内存被python持有,而是range( n )让python分配了很多的内存.退出test(),python回收内存,但是python并不释放了,而是让pool持有内存空间.</p>
<img src ="http://www.blogjava.net/yglwxl/aggbug/303916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yglwxl/" target="_blank">九宝</a> 2009-11-27 16:54 <a href="http://www.blogjava.net/yglwxl/archive/2009/11/27/303916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python- 映射 list</title><link>http://www.blogjava.net/yglwxl/archive/2009/05/14/270575.html</link><dc:creator>九宝</dc:creator><author>九宝</author><pubDate>Thu, 14 May 2009 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/yglwxl/archive/2009/05/14/270575.html</guid><wfw:comment>http://www.blogjava.net/yglwxl/comments/270575.html</wfw:comment><comments>http://www.blogjava.net/yglwxl/archive/2009/05/14/270575.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yglwxl/comments/commentRss/270575.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yglwxl/services/trackbacks/270575.html</trackback:ping><description><![CDATA[&gt;&gt;&gt;params={'s':'sv','a':'av','b':'bv'}<br />
&gt;&gt;&gt;params.keys()<br />
['a', 's', 'b']<br />
&gt;&gt;&gt;params.values()<br />
['av', 'sv', 'bv']<br />
&gt;&gt;&gt;params.items()<br />
[('a', 'av'), ('s', 'sv'), ('b', 'bv')]<br />
&gt;&gt;&gt;[k for k,v in params.items()]<br />
['a', 's', 'b']<br />
&gt;&gt;&gt;[v for k,v in params.items()]<br />
['av', 'sv', 'bv']<br />
&gt;&gt;&gt;["%s=%s" % (k,v) for k,v in params.items()]<br />
['a=av', 's=sv', 'b=bv']
<img src ="http://www.blogjava.net/yglwxl/aggbug/270575.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yglwxl/" target="_blank">九宝</a> 2009-05-14 11:57 <a href="http://www.blogjava.net/yglwxl/archive/2009/05/14/270575.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python study- List extend() and append()</title><link>http://www.blogjava.net/yglwxl/archive/2009/05/14/270562.html</link><dc:creator>九宝</dc:creator><author>九宝</author><pubDate>Thu, 14 May 2009 03:15:00 GMT</pubDate><guid>http://www.blogjava.net/yglwxl/archive/2009/05/14/270562.html</guid><wfw:comment>http://www.blogjava.net/yglwxl/comments/270562.html</wfw:comment><comments>http://www.blogjava.net/yglwxl/archive/2009/05/14/270562.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yglwxl/comments/commentRss/270562.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yglwxl/services/trackbacks/270562.html</trackback:ping><description><![CDATA[1. list extend (扩展) 与 append (追加) 的差别<br />
&gt;&gt;&gt;li=['a','b']<br />
&gt;&gt;&gt;li.extend(['c','d'])<br />
&gt;&gt;&gt;li<br />
['a', 'b', 'c', 'd']<br />
&gt;&gt;&gt;li.append(['e','f'])<br />
&gt;&gt;&gt;li<br />
['a', 'b', 'c', 'd',['e','f']]<br />
<br />
2. 搜索 搜索 list<br />
&gt;&gt;&gt;li.index('b')<br />
&gt;&gt;&gt;li<br />
1<br />
<br />
3<strong><font size="2">. List 运算符＋ 和 &#215;<br />
</font></strong>
<pre><code>&gt;&gt;&gt; </code><span class="userinput">li = ['a', 'b']</span></pre>
<pre><code>&gt;&gt;&gt; </code><span class="userinput">li = li + ['example', 'new']</span> </pre>
<pre><code>&gt;&gt;&gt; </code><span class="userinput">li</span></pre>
<pre><span style="color: teal">['a', 'b', 'example', 'new']</span></pre>
<pre><code>&gt;&gt;&gt; </code><span class="userinput">li += ['two']</span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></pre>
<pre><code>&gt;&gt;&gt; </code><span class="userinput">li</span></pre>
<pre><span style="color: teal">['a', 'b', 'example', 'new', 'two']</span></pre>
<pre><code>&gt;&gt;&gt; </code><span class="userinput">li = [1, 2] * 3</span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></pre>
<pre><code>&gt;&gt;&gt; </code><span class="userinput">li</span></pre>
<pre><span style="color: teal">[1, 2, 1, 2, 1, 2]</span></pre>
<br />
<br />
4.何谓 Python 中的 True<br />
&#183;0为false;&nbsp;&nbsp; 其它所有数值皆为 true。<br />
&#183;空串 ("") 为false;&nbsp; 其它所有字符串皆为 true。<br />
&#183;空list ([])为false;&nbsp; 其它所有字符串皆为 true。<br />
&#183;空 tuple (()) 为false;&nbsp; 其它所有字符串皆为 true。<br />
&#183;空 dictionary ({}) 为false;&nbsp; 其它所有字符串皆为 true。 
<img src ="http://www.blogjava.net/yglwxl/aggbug/270562.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yglwxl/" target="_blank">九宝</a> 2009-05-14 11:15 <a href="http://www.blogjava.net/yglwxl/archive/2009/05/14/270562.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>