2011-03-17 2 views
6

私は、 FreebsdにPython文字列を使って奇妙なメモリ使用パターンを観察しています。次のセッションを と考えてください。リスト内の累積文字が100MBになるように、いくつかの文字列を保持するリストを作成することが考えられます。FreeBSDでのPython文字列のメモリ使用

l = [] 
for i in xrange(100000): 
    l.append(str(i) * (1000/len(str(i)))) 

これは、予想通りに約100MBのメモリを使用し、「del l」はそれをクリアします。

l = [] 
for i in xrange(20000): 
    l.append(str(i) * (5000/len(str(i)))) 

これは165MBのメモリを使用しています。私は実際に のメモリ使用量がどこから来ているのか分かりません。 [両方のリストのサイズは同じです]

FreeBSD 7.2のPython 2.6.4。 Linux/Windowsでは、両方とも約 の100MBメモリしか使用しません。

アップデート:私は 'ps aux'を使ってメモリを測定しています。上記のコードスニペットの後にos.sytemを使用して実行できます。これらは別々に実行されました。

Update2:freebsd mallocsのメモリは2の倍数に見えます。したがって、5KBを割り当てると、実際には8KBが割り当てられます。私は確信していません。

+0

何まず最初のものを実行するコードの2番目の部分を実行してはどうですか?これは、オペレーティングシステム/ Pythonインタプリタとガベージコレクタがメモリをどのように管理しているかに関係しているので、もう一度165 MBになると思います。 – Hossein

+5

どのように使用するメモリを決定しますか?それが正しいと確信していますか? – steabert

答えて

0

答えはthis sagaです。私はあなたがやむを得ないメモリマネージャオーバーヘッドを目撃していると思います。

@Hosseinによれば、両方のコードスニペットを1回実行してからスワップしてみてください。

1

私の意見では、それはおそらくメモリ内の断片であろう。まず、255バイトより大きいメモリチャンクはCPythonでmallocで割り当てられます。あなたは、パフォーマンス上の理由から

Improving Python's Memory Allocator

に参照することができ、メモリ割り当てのほとんどは、malloc関数のように、整列アドレスを返します。例えば、あなたは

のようなアドレスを得ることはありません
0x00003 

それは4バイトで整列されていません、それはコンピュータがメモリにアクセスするために非常に遅くなるでしょう。したがって、mallocで取得するすべてのアドレスは、

0x00000 
0x00004 
0x00008 

などである必要があります。 4バイト整列は基本的な共通ルールであり、整列の実際の方針はOSの変形です。

あなたが話しているメモリ使用量はRSS(わからない)でなければなりません。ほとんどのOSでは、仮想メモリのページサイズは4Kです。あなたが割り当てるものについては、5000バイトのチャンクを格納するために2ページが必要です。メモリリークの例を見てみましょう。ここでは、アラインメントは256バイトであると仮定します。

0x00000 { 
...  chunk 1 
0x01388 } 
0x01389 { 
...  fragment 1 
0x013FF } 
0x01400 { 
...  chunk 2 
0x02788 } 
0x02789 { 
...  fragment 2 
0x027FF } 
0x02800 { 
...  chunk 3 
0x03B88 } 
0x03B89 { 
...  fragment 3 
0x04000 } 

あなたは非常に多くの断片がメモリ内にある見ることができるように、彼らが使用することはできませんが、それでも、彼らは、ページのメモリ空間を占有します。私はFreeBSDの整列方針が何であるか分かりませんが、このような理由で引き起こされたと思います。 Pythonでメモリを効率的に使用するには、あらかじめ割り当てられた大きなチャンク(bytearray)を使用し、使用するチャンクとして適切な番号を選ぶことができます(どれが最適かは、OSによって異なります)。

0

私はfreebsdのすべてのメモリアドレスを2の累乗に合わせる必要があると思います。したがって、すべてのPythonのメモリプールは、メモリに断片化されており、連続的ではありません。

は面白いものを見つけるためにいくつかの他のtoolを使用してみてください

関連する問題