2012-08-14 5 views
6

私は、メモリを割り当てる非常に簡単なスクリプトを持っています。は、サイズの大きいオブジェクトへの唯一の参照であり、その間はすべてheapypidstatのレポートを出力します。次のようにpython - メモリがカーネルに戻されない

from guppy import hpy 
import time 
import sys 
import os 

''' 
1) print heapy and pidstat report after starting and before actually doing any work 
2) allocate some memory in a simple 2d array 
3) print heapy and pidstat report 
4) del the d2 array (attempt at garbage collection) 
5) print heapy and pidstat report 
6) sleep so pidstat can continue to be run to check on memory 
''' 

def pidstat(msg): 
    print '===============================' 
    print msg 
    os.system('pidstat -r -p %s' % os.getpid()) 
    print '+++++++++++++++++++++++++++++++' 
    print hpy().heap()[0] 
    print '===============================' 

pidstat('before doing anything') 
docs = [] 
for doc in range(0, 10000): 
    docs.append([j for j in range(0, 1000)]) 

pidstat('after fetching all the docs into memory') 
del docs 

pidstat('after freeing the docs') 
time.sleep(60) 

出力はなります:

 
=============================== 
before doing anything 
Linux 2.6.38-15-generic (hersheezy)  08/14/2012 _x86_64_ (4 CPU) 

01:05:20 PM  PID minflt/s majflt/s  VSZ RSS %MEM Command 
01:05:20 PM  5360  0.44  0.00 44768 9180 0.11 python 
+++++++++++++++++++++++++++++++ 
Partition of a set of 19760 objects. Total size = 1591024 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 19760 100 1591024 100 1591024 100 str 
=============================== 
=============================== 
after fetching all the docs into memory 
Linux 2.6.38-15-generic (hersheezy)  08/14/2012 _x86_64_ (4 CPU) 

01:05:21 PM  PID minflt/s majflt/s  VSZ RSS %MEM Command 
01:05:21 PM  5360  8.95  0.00 318656 279120 3.49 python 
+++++++++++++++++++++++++++++++ 
Partition of a set of 7431665 objects. Total size = 178359960 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 7431665 100 178359960 100 178359960 100 int 
=============================== 
=============================== 
after freeing the docs 
Linux 2.6.38-15-generic (hersheezy)  08/14/2012 _x86_64_ (4 CPU) 

01:05:29 PM  PID minflt/s majflt/s  VSZ RSS %MEM Command 
01:05:29 PM  5360  40.23  0.00 499984 460480 5.77 python 
+++++++++++++++++++++++++++++++ 
Partition of a set of 19599 objects. Total size = 1582016 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0 19599 100 1582016 100 1582016 100 str 
=============================== 

を、私はこのことを確認することができますどのようにスクリプトを実行した後、heapyはpidstatが私に反対を伝えながら、使用されている多くのメモリがあってはならないことを私に伝えますメモリがオペレーティングシステムに返されますか?

+1

[なぜdjangoで大きなクエリ(または一連のクエリ)の後にメモリがシステムに解放されないのですか?](http://stackoverflow.com/questions/5494178/why-doesnt-memory-get-大量のクエリーやクエリーの後にシステムに公開されました) –

答えて

3

メモリがpythonプロセス内で再利用可能になったときと、それがOSにリリースされたときとでは異なることがあります。特に、標準のPythonインタプリタ(CPython)は、特定の種類のオブジェクトに対して独自のプールと空きリストを保持します。これらのプール自体でメモリを再利用しますが、使用されるとOSに解放されることはありません。

詳細はthisを参照してください。

+1

私は投稿された質問に答えると信じています。私の本当の疑問は、1日に1回の非常に短い時間の間に1トンのメモリ(システムのメモリの約60%)を割り当てる長期実行Pythonデーモンを持つことに由来します。実行終了後、私の参照をクリーンアップしても、メモリの使用率は高いままです。一般的なアドバイスは?あなたが投稿したリンクは、最初の場所にその多くのメモリを割り当ててはいけないと言われました... – Hersheezy

+0

2番目のスクリプトやそのような性質のもので大量のメモリを必要とする可能性はありますか?メモリを必要とする処理が開始されたときにデーモンの2番目のインスタンスを起動し、その後処理を終了するだけで(2番目のインスタンスを継続して実行できるようにする) – kindall

+2

@Hersheezy:この答えは妥当と思われますが、間違っています。 CPython *は時々メモリを解放することができます。参照してください[私のコメント](http://stackoverflow.com/questions/11957539/python-memory-not-being-given-back-to-kernel#comment15934886_11957625) – jfs

1

このメモリがオペレーティングシステムに返されるようにするにはどうすればよいですか?

一般的にはそうではありません。 Pythonは 'arenas'にメモリを割り当てます。インタープリタで参照が削除されても、後で使用するメモリ領域を保持します。私は、新しいバージョンのpythonに、完全に空であればアリーナをアンクレームする仕組みがあると思います。しかし、あなたはあなたのオブジェクトが置かれる場所を制御することはできません。

+2

2005年に[pythonが空のアリーナを公開する可能性があります](http://bugs.python.org/issue1123430)。 ](http://bugs.python.org/msg134992) – jfs

関連する問題