目次
Python によるメモリの管理方法" >Python によるメモリの管理方法
Python の参照サイクル" >Python の参照サイクル
Python ガベージ コレクター (gc)" >Python ガベージ コレクター (gc)
如何使用 gc 模块" >如何使用 gc 模块
使用 gc 调试垃圾收集" >使用 gc 调试垃圾收集
避免 Python 内存管理中的陷阱" >避免 Python 内存管理中的陷阱
注意对象范围" >注意对象范围
使用 weakref避免引用循环" >使用 weakref避免引用循环
参照サイクルの手動解除" >参照サイクルの手動解除
ホームページ バックエンド開発 Python チュートリアル Python のメモリ管理の仕組みを理解していますか?

Python のメモリ管理の仕組みを理解していますか?

Apr 12, 2023 pm 04:25 PM
python メモリ管理

Python は開発者に多くの利便性を提供します。その最大の利点の 1 つは、実質的に心配のないメモリ管理です。開発者は、Python でオブジェクトやデータ構造のメモリを手動で割り当て、追跡、解放する必要がなくなりました。ランタイムがこれらの作業をすべて実行してくれるため、ユーザーはマシンレベルの詳細を議論するのではなく、実際の問題の解決に集中できます。

Python のメモリ管理の仕組みを理解していますか?

# それでも、経験の浅い Python ユーザーであっても、Python のガベージ コレクションとメモリ管理がどのように機能するかを理解することは有益です。これらのメカニズムを理解すると、より複雑なプロジェクトで発生する可能性のあるパフォーマンスの問題を回避できます。 Python の組み込みツールを使用して、プログラムのメモリ管理動作を監視することもできます。

Python によるメモリの管理方法

すべての Python オブジェクトには、参照カウントとも呼ばれる参照カウントがあります。 refcount は、特定のオブジェクトへの参照を保持する他のオブジェクトの合計数です。オブジェクトへの参照を追加または削除すると、数値が増減します。オブジェクトの参照カウントがゼロになると、オブジェクトの割り当てが解除され、そのメモリが解放されます。

リファレンスとは何ですか?名前による、または別のオブジェクトのアクセサーを介したオブジェクトのコンテンツへのアクセスを許可します。

これは簡単な例です:

x = "Hello there"
ログイン後にコピー

このコマンドを Python に発行すると、内部で 2 つのことが起こります:

  1. 文字列「Hello there」が作成されます。 Python オブジェクトとしてメモリに保存されます。
  2. 名前 x がローカル名前空間に作成され、オブジェクトを指します。これにより、参照カウントが 1 から 1 に増加します。

y = x とすると、参照カウントは再び 2 に増加します。

xandy がスコープ外になるか名前空間から削除されるたびに、文字列の参照カウントは名前ごとに 1 ずつ減ります。 x と y の両方が範囲外になるか、削除されると、文字列の参照カウントは 0 になり、削除されます。

ここで、次のように文字列を含むリストを作成するとします。

x = ["Hello there", 2, False]
ログイン後にコピー

リスト自体が削除されるか、文字列を含む要素がリストから削除されるまで、文字列はメモリ内に残ります。 。これらの操作のいずれも、文字列への参照を保持している唯一のものを消去します。

次の例を考えてみましょう:

x = "Hello there" y = [x]
ログイン後にコピー

から最初の要素 y を削除するか、リスト y を完全に削除しても、文字列はまだメモリ内にあります。これは、名前 x にそれへの参照が含まれているためです。

Python の参照サイクル

ほとんどの場合、参照カウントは正常に機能します。ただし、2 つのオブジェクトがそれぞれ他方への参照を保持している状況に遭遇することがあります。これを基準期間といいます。この場合、オブジェクトの参照カウントがゼロになることはなく、メモリから削除されることもありません。

これは不自然な例です:

x = SomeClass()
y = SomeOtherClass()
x.item = y
y.item = x
ログイン後にコピー

x と y は相互参照を保持しているため、他のものがどちらかを参照していなくても、システムから削除されることはありません。

Python 自体のランタイムがオブジェクトの参照サイクルを生成することは、実際には非常に一般的です。例としては、例外自体への参照を含むトレースバック オブジェクトを含む例外があります。

以前のバージョンの Python では、これが問題でした。参照サイクルを持つオブジェクトは時間の経過とともに蓄積される可能性があり、これは長時間実行されるアプリケーションにとって大きな問題になります。しかし、Python はそれ以来、参照サイクルを管理するためにサイクル検出およびガベージ コレクション システムを導入しました。

Python ガベージ コレクター (gc)

Python のガベージ コレクターは、参照サイクルを持つオブジェクトを検出します。これは、「コンテナ」であるオブジェクト (リスト、辞書、カスタム クラス インスタンスなど) を追跡し、どのオブジェクトが他の場所からもアクセスできないかを判断することによって行われます。

これらのオブジェクトが選択されると、ガベージ コレクターは参照カウントが安全にゼロになることを確認してそれらを削除します。

Python オブジェクトの大部分には参照サイクルがないため、ガベージ コレクターを 24 時間年中無休で実行する必要はありません。代わりに、ガベージ コレクターはいくつかのヒューリスティックを使用して、実行頻度を減らし、毎回できるだけ効率的に実行します。

Python インタープリターは、開始されると、割り当てられているが解放されていないオブジェクトの数を追跡します。 Python オブジェクトの大部分は存続期間が短いため、すぐに表示されて消えます。しかし、時間が経つにつれて、より長寿命のオブジェクトが出現するでしょう。このようなオブジェクトが一定数以上蓄積されると、ガベージ コレクターが実行されます。

ガベージ コレクターが実行されるたびに、コレクションで生き残ったすべてのオブジェクトが収集され、それらが世代と呼ばれるグループに配置されます。これらの「第 1 世代」オブジェクトは、参照サイクル中にスキャンされる頻度が低くなります。ガベージ コレクターで生き残った第 1 世代のオブジェクトは、最終的には第 2 世代に移行され、スキャンの頻度が低くなります。

同样,垃圾收集器不会跟踪所有内容。例如,像用户创建的类这样的复杂对象总是被跟踪。但是不会跟踪仅包含简单对象(如整数和字符串)的字典,因为该特定字典中的任何对象都不会包含对其他对象的引用。不能保存对其他元素(如整数和字符串)的引用的简单对象永远不会被跟踪。

如何使用 gc 模块

通常,垃圾收集器不需要调整即可运行良好。Python 的开发团队选择了反映最常见现实世界场景的默认值。但是如果你确实需要调整垃圾收集的工作方式,你可以使用Python 的 gc 模块。该gc模块为垃圾收集器的行为提供编程接口,并提供对正在跟踪的对象的可见性。

gc当你确定不需要垃圾收集器时,你可以做的一件有用的事情是关闭它。例如,如果你有一个堆放大量对象的短运行脚本,则不需要垃圾收集器。脚本结束时,所有内容都将被清除。为此,你可以使用命令禁用垃圾收集器gc.disable()。稍后,你可以使用 重新启用它gc.enable()。

你还可以使用 手动运行收集周期gc.collect()。一个常见的应用是管理程序的性能密集型部分,该部分会生成许多临时对象。你可以在程序的该部分禁用垃圾收集,然后在最后手动运行收集并重新启用收集。

另一个有用的垃圾收集优化是gc.freeze(). 发出此命令时,垃圾收集器当前跟踪的所有内容都被“冻结”,或者被列为免于将来的收集扫描。这样,未来的扫描可以跳过这些对象。如果你有一个程序在启动之前导入库并设置大量内部状态,那么你可以gc.freeze()在所有工作完成后发出。这使垃圾收集器不必搜寻那些无论如何都不太可能被删除的东西。(如果你想对冻结的对象再次执行垃圾收集,请使用gc.unfreeze().)

使用 gc 调试垃圾收集

你还可以使用它gc来调试垃圾收集行为。如果你有过多的对象堆积在内存中并且没有被垃圾收集,你可以使用gc's 检查工具来找出可能持有对这些对象的引用的对象。

如果你想知道哪些对象持有对给定对象的引用,可以使用gc.get_referrers(obj)列出它们。你还可以使用gc.get_referents(obj)来查找给定对象引用的任何对象。

如果你不确定给定对象是否是垃圾收集的候选对象,gc.is_tracked(obj)请告诉你垃圾收集器是否跟踪该对象。如前所述,请记住垃圾收集器不会跟踪“原子”对象(例如整数)或仅包含原子对象的元素。

如果你想亲自查看正在收集哪些对象,可以使用 设置垃圾收集器的调试标志gc.set_debug(gc.DEBUG_LEAK|gc.DEBUG_STATS)。这会将有关垃圾收集的信息写入stderr。它将所有作为垃圾收集的对象保留在只读列表中。

避免 Python 内存管理中的陷阱

如前所述,如果你在某处仍有对它们的引用,则对象可能会堆积在内存中而不会被收集。这并不是 Python 垃圾收集本身的失败。垃圾收集器无法判断你是否不小心保留了对某物的引用。

让我们以一些防止对象永远不会被收集的指针作为结尾。

注意对象范围

如果你将对象 1 指定为对象 2 的属性(例如类),则对象 2 将需要超出范围,然后对象 1 才会:

obj1 = MyClass()
obj2.prop = obj1
ログイン後にコピー

更重要的是,如果这种情况发生在某种其他操作的副作用中,例如将对象 2 作为参数传递给对象 1 的构造函数,你可能不会意识到对象 1 持有一个引用:

obj1 = MyClass(obj2)
ログイン後にコピー

另一个例子:如果你将一个对象推入模块级列表并忘记该列表,则该对象将一直保留,直到从列表中删除,或者直到列表本身不再有任何引用。但是如果该列表是一个模块级对象,它可能会一直存在,直到程序终止。

简而言之,请注意你的对象可能被另一个看起来并不总是很明显的对象持有的方式。

使用 weakref避免引用循环

Python 的 weakref 模块允许你创建对其他对象的弱引用。弱引用不会增加对象的引用计数,因此只有弱引用的对象是垃圾回收的候选对象。

一个常见的用途weakref是对象缓存。你不希望仅仅因为它具有缓存条目而保留引用的对象,因此你将 aweakref用于缓存条目。

参照サイクルの手動解除

最後に、特定のオブジェクトに別のオブジェクトへの参照が含まれていることがわかっている場合は、いつでもそのオブジェクトへの参照を手動で解除できます。たとえば、instance_of_class.ref = other_object がある場合、instance_of_class を削除する準備ができたら、instance_of_class.ref = None を設定できます。

Python のメモリ管理の仕組みを理解することで、そのガベージ コレクション システムが Python プログラムのメモリの最適化にどのように役立つか、また、標準ライブラリなどで提供されるモジュールを使用してメモリ使用量とガベージ コレクションを制御する方法を見ていきます。 。

元のタイトル: Python ガベージ コレクションと gc モジュール

以上がPython のメモリ管理の仕組みを理解していますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPおよびPython:さまざまなパラダイムが説明されています PHPおよびPython:さまざまなパラダイムが説明されています Apr 18, 2025 am 12:26 AM

PHPは主に手順プログラミングですが、オブジェクト指向プログラミング(OOP)もサポートしています。 Pythonは、OOP、機能、手続き上のプログラミングなど、さまざまなパラダイムをサポートしています。 PHPはWeb開発に適しており、Pythonはデータ分析や機械学習などのさまざまなアプリケーションに適しています。

PHPとPythonの選択:ガイド PHPとPythonの選択:ガイド Apr 18, 2025 am 12:24 AM

PHPはWeb開発と迅速なプロトタイピングに適しており、Pythonはデータサイエンスと機械学習に適しています。 1.PHPは、単純な構文と迅速な開発に適した動的なWeb開発に使用されます。 2。Pythonには簡潔な構文があり、複数のフィールドに適しており、強力なライブラリエコシステムがあります。

PHPとPython:彼らの歴史を深く掘り下げます PHPとPython:彼らの歴史を深く掘り下げます Apr 18, 2025 am 12:25 AM

PHPは1994年に発信され、Rasmuslerdorfによって開発されました。もともとはウェブサイトの訪問者を追跡するために使用され、サーバー側のスクリプト言語に徐々に進化し、Web開発で広く使用されていました。 Pythonは、1980年代後半にGuidovan Rossumによって開発され、1991年に最初にリリースされました。コードの読みやすさとシンプルさを強調し、科学的コンピューティング、データ分析、その他の分野に適しています。

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Sublime Code Pythonを実行する方法 Sublime Code Pythonを実行する方法 Apr 16, 2025 am 08:48 AM

PythonコードをSublimeテキストで実行するには、最初にPythonプラグインをインストールし、次に.pyファイルを作成してコードを書き込み、Ctrl Bを押してコードを実行する必要があります。コードを実行すると、出力がコンソールに表示されます。

vscodeでコードを書く場所 vscodeでコードを書く場所 Apr 15, 2025 pm 09:54 PM

Visual Studioコード(VSCODE)でコードを作成するのはシンプルで使いやすいです。 VSCODEをインストールし、プロジェクトの作成、言語の選択、ファイルの作成、コードの書き込み、保存して実行します。 VSCODEの利点には、クロスプラットフォーム、フリーおよびオープンソース、強力な機能、リッチエクステンション、軽量で高速が含まれます。

Visual StudioコードはPythonで使用できますか Visual StudioコードはPythonで使用できますか Apr 15, 2025 pm 08:18 PM

VSコードはPythonの書き込みに使用でき、Pythonアプリケーションを開発するための理想的なツールになる多くの機能を提供できます。ユーザーは以下を可能にします。Python拡張機能をインストールして、コードの完了、構文の強調表示、デバッグなどの関数を取得できます。デバッガーを使用して、コードを段階的に追跡し、エラーを見つけて修正します。バージョンコントロールのためにGitを統合します。コードフォーマットツールを使用して、コードの一貫性を維持します。糸くずツールを使用して、事前に潜在的な問題を発見します。

メモ帳でPythonを実行する方法 メモ帳でPythonを実行する方法 Apr 16, 2025 pm 07:33 PM

メモ帳でPythonコードを実行するには、Python実行可能ファイルとNPPEXECプラグインをインストールする必要があります。 Pythonをインストールしてパスを追加した後、nppexecプラグインでコマンド「python」とパラメーター "{current_directory} {file_name}"を構成して、メモ帳のショートカットキー「F6」を介してPythonコードを実行します。

See all articles