Pythonメモリ管理および参照カウント
2281 ワード
動的言語としてpythonの重要な概念の一つは、動的タイプ、すなわちオブジェクトのタイプとメモリの占有量が実行時に決定されることです.(Why?)実行すると、解釈器は構文と右の操作数に基づいて新しいオブジェクトのタイプを決定します.ダイナミックタイプの実装は、参照とオブジェクトの分離によって達成されます.オブジェクトはメモリに格納されたデータエンティティであり、リファレンス(reference)はオブジェクトへのカプセル化されたポインタとして理解されます.しかし、操作はより便利で安全です.C++の参照がポインタ操作の簡略化とカプセル化であるように.pythonでは、メモリの管理、すなわち割り当てと回収は、python解釈器によって行われ、プログラマーはあまり関心を持つ必要はありません.あるいは、参照はオブジェクトの別名として理解することもでき、1つのオブジェクトは複数の個別名でそれを指すことができる.例えば、後のコードの3.14という浮動小数点オブジェクトは、xもyもそのオブジェクトを指しており、別名と見なすことができます.一人で張某という名前で、小名で張三と呼ぶことができるように.pythonでは、オブジェクトを作成するときに、解釈器がメモリの割り当てを担当し、内部にリファレンスカウンタというものがオブジェクトに変数を割り当てられたときに1に設定されます.オブジェクトを変数に割り当てると、オブジェクトの参照が変数に割り当てられます.このオブジェクトを他の変数に再び割り当てると、カウンタ+1が参照されます.次のようになります.
最初の行のコードでは、浮動小数点型のオブジェクトが作成され、xという変数に参照が割り当てられます.これは参照カウンタの値が1です.次に、xをyに割り当てます.すなわち、カウンタ+1、値2を参照しながら、この浮動小数点オブジェクトの参照をyに再び割り当てます.すなわち、xをyに付与すると、新しいオブジェクトが作成されない.メモリ内のデータ・オブジェクトは依然として1つしかありませんが、2つの変数xがあり、yは同じオブジェクトを指します.この点、C/C++とは全く違います.でもね、前述のようにC/C++のポインタに似ています.次のようになります.
上記のコードでは、int型変数tmpを定義して10に初期化し、次に、ポインタpがtmpオブジェクトを指すメモリを定義します.すなわち、tmpと*pは同じメモリオブジェクトを指す.しかし、pythonは最下位の作業を行い、通常の変数を操作するように操作するだけでポインタのような効果を得ることができます.pythonに戻ると、x,yのいずれかの値を変更すると、もう1つは影響を受けません.次のようになります.
このとき,出力を行うとxの値は5であり,yの値は3.14である.x=「A」文を実行すると、実際には新しいオブジェクトが作成され、その参照がxに割り当てられるからです.このとき,xとyはすでに2つの非相関の2つの変数である.異なるオブジェクトを指しているからです.この文を実行すると同時に、yが実行する3.14という浮動小数点数オブジェクトの参照カウンタが1減算される.参照カウンタの値がゼロ、すなわち変数がこのオブジェクトを指していない場合、システムは自動的にこのオブジェクトを破棄し、メモリを回収します.(もちろん、実装上は、必ずしも参照カウンタが0であるとは限らず、すぐに回収し、いくつかの回収策があるかもしれません.)また、xは最初は浮動小数点型オブジェクトを指していたが、現在は文字列を指していることがわかる.Pythonでは、変数名はオブジェクトを指すだけで、オブジェクトのタイプには関係ありません.ここでは弱いタイプ、強いタイプについては、あまり分からないので、これ以上は触れません.(Right?)参照カウントに戻ると、1>オブジェクトがx=3.142>または別の別名がy=x 3>またはパラメータとして関数(新しいローカル参照)foobar(x)4>またはコンテナオブジェクトと呼ばれる要素(コンテナ?)に渡される4つの場合、参照カウンタが増加します.myList = [123, x, ‘xyz’]
一方、以下の場合、参照カウンタは減少します.1>foobar()関数の終了時など、ローカル参照がその作用範囲から離れています.2>オブジェクトの別名表示破棄dely 3>オブジェクトの別名が他のオブジェクトx=1234>オブジェクトに付与されてウィンドウオブジェクトからmyListが除去する.remove(x)5>ウィンドウオブジェクト自体がdel myListdel文を破棄すると、オブジェクトの参照が削除されます.2つの効果があります.1>現在のネームスペースから変数名を削除2>オブジェクトの参照数-1
転載は住所を明記してください.http://www.qyspaces.com/?p=272
x = 3.14
y = x
最初の行のコードでは、浮動小数点型のオブジェクトが作成され、xという変数に参照が割り当てられます.これは参照カウンタの値が1です.次に、xをyに割り当てます.すなわち、カウンタ+1、値2を参照しながら、この浮動小数点オブジェクトの参照をyに再び割り当てます.すなわち、xをyに付与すると、新しいオブジェクトが作成されない.メモリ内のデータ・オブジェクトは依然として1つしかありませんが、2つの変数xがあり、yは同じオブジェクトを指します.この点、C/C++とは全く違います.でもね、前述のようにC/C++のポインタに似ています.次のようになります.
int tmp = 10;
int *p = &tmp;
上記のコードでは、int型変数tmpを定義して10に初期化し、次に、ポインタpがtmpオブジェクトを指すメモリを定義します.すなわち、tmpと*pは同じメモリオブジェクトを指す.しかし、pythonは最下位の作業を行い、通常の変数を操作するように操作するだけでポインタのような効果を得ることができます.pythonに戻ると、x,yのいずれかの値を変更すると、もう1つは影響を受けません.次のようになります.
x = 3.14
y = x
x = “A”
このとき,出力を行うとxの値は5であり,yの値は3.14である.x=「A」文を実行すると、実際には新しいオブジェクトが作成され、その参照がxに割り当てられるからです.このとき,xとyはすでに2つの非相関の2つの変数である.異なるオブジェクトを指しているからです.この文を実行すると同時に、yが実行する3.14という浮動小数点数オブジェクトの参照カウンタが1減算される.参照カウンタの値がゼロ、すなわち変数がこのオブジェクトを指していない場合、システムは自動的にこのオブジェクトを破棄し、メモリを回収します.(もちろん、実装上は、必ずしも参照カウンタが0であるとは限らず、すぐに回収し、いくつかの回収策があるかもしれません.)また、xは最初は浮動小数点型オブジェクトを指していたが、現在は文字列を指していることがわかる.Pythonでは、変数名はオブジェクトを指すだけで、オブジェクトのタイプには関係ありません.ここでは弱いタイプ、強いタイプについては、あまり分からないので、これ以上は触れません.(Right?)参照カウントに戻ると、1>オブジェクトがx=3.142>または別の別名がy=x 3>またはパラメータとして関数(新しいローカル参照)foobar(x)4>またはコンテナオブジェクトと呼ばれる要素(コンテナ?)に渡される4つの場合、参照カウンタが増加します.myList = [123, x, ‘xyz’]
一方、以下の場合、参照カウンタは減少します.1>foobar()関数の終了時など、ローカル参照がその作用範囲から離れています.2>オブジェクトの別名表示破棄dely 3>オブジェクトの別名が他のオブジェクトx=1234>オブジェクトに付与されてウィンドウオブジェクトからmyListが除去する.remove(x)5>ウィンドウオブジェクト自体がdel myListdel文を破棄すると、オブジェクトの参照が削除されます.2つの効果があります.1>現在のネームスペースから変数名を削除2>オブジェクトの参照数-1
転載は住所を明記してください.http://www.qyspaces.com/?p=272