メモリ機構のpython変数

言語を使いやすいよう、そして大規模なライブラリと、Pythonは手のひらサイズの手の中にプログラマーとして記述することができないと同時に、究極の運転効率の追求にあれば、自分自身をプログラミングすることは、変換人間の心は、コンピュータ技術の考え方ですコンピュータのメモリに限定されるものではなく、Pythonは間違いなく最も便利な言語です。

資格のプログラマーとして、私たちは自然に使用するのpythonに加えて、自己を超えて飛行する、だけでなく、パイソン、その動作原理の内部を探索するために、Pythonプログラミングの矢面に立つ、これらを知っている、なぜ知っている必要があります変数を使用する必要がありますそしてその背後にあるメカニズムを動作させます。

注:Linuxプラットフォームで書かれた次の例、python2.7を使用して

参考メカニズム

Pythonの変数 - メモリモデルは、より多くのC ++の参照メカニズムのようなものです、pythonの各変数は、メモリ領域を占有しないことがあり、より多くのメモリ変数を参照するように、あなたはこの変数によってメモリ内のデータにアクセスすることができ、ギブ例:

>>>a=10
>>>b=a
>>>c=[1,2,3,4]
>>>d=c
>>>print "%x%x"  %(id(a),id(b))
>>>print "%x%x"  %(id(c),id(d))

出力:

b51080.b51080
7f28bf69b758.7f28bf69b758  

ここで、ID()は、Pythonシステムリターンオブジェクトメモリーアドレスを開始する機能です。

結果から、変数のアドレスに対応し、B、CおよびDは、実際には、我々は、変数とBを使用する場合、同じオブジェクトを使用しているのと同じアドレスであり、そして、Bは、対象物であります参照は、我々は()システム関数sys.getrefcount参照番号を介してオブジェクトを表示することができます。

>>>import sys
>>>a=257
>>>print sys.getrefcount(a)
>>>b=a
>>>print sys.getrefcount(a)

出力:

2
3

明らかに、これは、それらの私たちの期待に同じアドレスで、AとBのためになりませんが、結果は1,2である必要があり、2,3なぜそれで?

sys.getrefcount()関数呼び出しは、また引数は一度、そう2,3が結果として引用されているためです。

小さなデータキャッシュメカニズム

私たちは時にPythonの変数の割り当てメモリメカニズム前述した、物事はとても完璧な終わりですか?

そして、いや!

私たちは例を見てみましょう:

>>> a=10
>>> b=10
>>> print "%x.%x" %(id(a),id(b))

出力:

b51080.b51080

結果を参照してください、私はゆっくりと慎重にそれを拭く三回医療アルコール濃度の95%を取る、私の眼鏡を脱いして、間違っている、いない見た後に入れて!これらの2つの変数は、同じアドレスまたはコンテンツを参照してください、この時間は、2つの変数が同じアドレスそれを参照してくださいなぜ2つの変数が割り当てが初期化されていない、独立している、または初期化するには?

答えは次のとおりです。

在Python中,Python会有一个缓存对象的机制,以便重复使用。当我们创建多个等于1的引用时,实际上是让所有这些引用指向同一个对象,以达到节省资源的目的  

だから、これはです!

しかし、慎重に考えて、それは右、ではないのですか?各データ・キャッシュ場合は、メモリ空間のその極端な廃棄物を意味するでしょうか?またはメモリ回復メカニズムは、ガベージメモリに一度時間をかけて回収されるのでしょうか?
私たちは例を見てみましょう:

>>> a=100
>>> b=100
>>> print "%d%d" %(id(a),id(b))
>>> a=256
>>> b=256
>>> print "%d%d" %(id(a),id(b))
>>> a=257 
>>> b=257
>>> print "%d%d" %(id(a),id(b))

出力:

5223836.5223836
5225932.5225932
5241840.5241864  

少ない256以上ある結果から、この値は、リサイクルシステムキャッシュになり、> 256は、キャッシュ・システムは、3回の実験の(もちろん、単なる結果ではないとき、ブロガーも試み、その後の多くの値ではなく、リストへ)

私たちは)(すなわちsys.getrefcount、この問題を確認するための別の方法を来ります:

>>>import sys
>>>a=10
>>>print sys.getrefcount(a)
>>>a=257
>>>print sys.getrefcount(a)

出力は次のようになります。

15
2

結果は明白である(代わりに上記1で説明されている理由2)、この値は、システム・キャッシュ10、および他の場所で参照の数、及び2 257の値です。

他のタイプのデータもあれば、再び質問がそう?私たちは、その後、参照します

>>>a="downey"
>>>b="downey"
>>>print "%d%d" %(id(a),id(b))

結果は以下のとおりです。

39422528.39422528

短い文字列のキャッシュメカニズムがあります

次に、リスト:

>>>a=[1,2,3]
>>>b=[1,2,3]
>>>print "%d%d" %(id(a),id(b))
39704576.39745176

ここにあなたが見ることができるから、リストなしキャッシュメカニズム、Pythonのキャッシュ機構は、変数のすべてのタイプのためではありません

可変キャッシュ結論

様々な実験や調査ショーによると、結果はそれを示しました:

  • Pythonの変数は、実際にヒープメモリへの参照であり、タグがエンティティとして理解することができ、異なる変数の間(例えば、= b)はコピーのコピー、それらが同じエンティティによって表されるオブジェクト
  • Pythonの意志(256を含む)-5-256及び複数の配布破壊のオーバーヘッドを節約するために整数データ・キャッシュの短い文字列

私の友人の思考は助けることはできませんが、お願いしたいと思いますし、整数データは、これらの短い文字列が本当に大きく、それのパフォーマンスを改善しているキャッシュするように、ここを参照してください?Pythonのコードは、整数の変数の数を持つことができますか?

:答えは整数変数メモリオブジェクトに対応する整数が、オブジェクトが可変整数型に対応する整数のメモリだけでなく、容器は、変数の参照整数整形素子であってもよいです

あなたはまだ疑問を持っている場合は、我々は次の例を見てみましょう:

>>> import sys
>>> a=1
>>> sys.getrefcount(a)
128
>>> b=[1,2,3]
>>> sys.getrefcount(a)
129

印刷の結果から、整数変数a = 1は、1つの意味ポインティング物体、参照1、B [0]としても1に初期化され、同じ、B [0]は、また、対象物1への参照でありますすべてのコンテナは、この形式であるため、ここを参照してください、観客の紳士淑女が、それを理解する必要があります。

pythonについての変数はメモリ変数のメカニズムは、このブログ記事を参照することができます影響を与えます場合はPythonの関数呼び出しのパラメータの受け渡し

ガーベジコレクション

今、メモリメカニズムは、オブジェクトに割り当てられたメモリの定義に使用された場合、非常に簡単で、かつメモリのリサイクルが原因でメモリの回復の過程では、それほど単純ではありません、メカニズムは、メモリ割り当ての配布と回収を伴う必要があります来ますPythonは、他のタスクを実行することはできませんので、頻繁にガベージコレクションが深刻な効率の問題を引き起こす可能性があり、メモリの回復間隔は、メモリの深刻な浪費につながることができます長すぎる、それは一般的にのみ、特定の時間内にガベージコレクションを開始しています。

Pythonの実行、および記録された割当解除の数、2つの値の間の差が一定値よりも大きい場合にのみ、すなわち、

分配次数-释放次数>触发回收的阈值

場合は、Pythonのガベージコレクションは、我々は、しきい値を取得するためにGET_THRESHOLD()メソッドを使用することができます。

>>>import gc
>>>print gc.get_threshold()

出力:

(700,10,10)

700は、回収されたメモリのトリガーしきい値です。しかし、2つの10のバックは、それが何を意味するのでしょうか?

また、メモリの回復のためのメカニズムと呼ばれる世代の回復で、この戦略の基本的な前提がある:長いオブジェクトが存在する時、少ない長期的にいくつかのオブジェクト自信の使用を与えるゴミオブジェクトになるために。

Pythonのは、0,1,2、すべての被験者は3つの世代に分けました。すべてのオブジェクトは、新世代0オブジェクトです。オブジェクトはまだ、生きている経験豊富な世代のガベージコレクションである場合には、それは次のターゲットとして分類されています。ガベージコレクションが開始すると、それは世代0のオブジェクトのすべてをスキャンします。一定回数後の世代0ガベージコレクション場合は、世代0と世代1のスキャンとクリーニングを開始します。世代はガベージコレクションの特定の数を経験してきたとき、それはすべてのオブジェクトをスキャンする、0,1,2に開始します

すなわち、2回以上のGET_THRESHOLD((700、10、10)は、2つの10のリターンが返されます)。ガベージコレクションごとに10世代、1世代2ガベージコレクションを有することになる。換言すれば、すべての10世代0ガベージコレクションは、ジェネレーション1のガベージコレクション後満たします。

我々はまた、手動で回復のトリガしきい値を調整することができ、スマートな友人は、このメソッドを推測することができ、かつ、GETがあるので、対応するセットにバインドされます。

import gc
gc.set_threshold(600,8,7)

システム回復のために受動的に待機することに加えて、もちろん、手動でメモリリコールを実行することができます。

import gc
gc.collect()  

実際には、イェジンハオのJava、Pythonや、メモリのメカニズム各言語は基本的にそのメモリのプロセスに、より多くの複雑な詳細があるでしょう、言語の効率に影響を与えるだろうが、ここでは不法侵入のための唯一の一般的なフレームワークを導入しました、偉大な神の訂正や追加の通過を歓迎しました。

この記事は間違っているものを、ウェルカムメッセージで見つかったため、私の友人や質問があればよく、Pythonの変数のメモリメカニズムに関する問題は、ここで停止します

個人Eメール:[email protected]
オリジナルのブログは、ソースを明記してください!

私は、バグがZhanshenない、茂みを通してあなたのプロジェクトの早期実現を願っています。
(終了)

公開された296元の記事 ウォンの賞賛221 ビュー540 000 +

おすすめ

転載: blog.csdn.net/qq_36387683/article/details/104988710