目次
1 参照カウント
1.1 参照カウント アルゴリズムの原理
カウンタの増加と減少をよりよく理解するために、実際のコードを実行して、一目でそれを明確に確認します。
1.3.1 参照カウントの利点
循環参照。これは参照カウントの致命的な欠陥であり、参照カウントには解決策がないため、他のガベージ コレクション アルゴリズムを使用して補う必要があります。
3 分代收集
3.1 分代收集原理
3.2 触发GC时机
ホームページ バックエンド開発 Python チュートリアル Python のガベージ コレクション メカニズムをマスターする方法。

Python のガベージ コレクション メカニズムをマスターする方法。

May 08, 2023 pm 10:10 PM
python

Python の自動ガベージ コレクション メカニズムのおかげで、Python でオブジェクトを作成するときにオブジェクトを手動で解放する必要はありません。これは開発者にとって非常に使いやすく、開発者は低レベルのメモリ管理について心配する必要がなくなります。ただし、ガベージ コレクションのメカニズムを理解していないと、作成する Python コードは非常に非効率なものになることがよくあります。

ガベージ コレクション アルゴリズムは多数あります。主なものは、参照カウントマーククリアランス世代コレクションなどです。

python では、ガベージ コレクション アルゴリズムは主に 参照カウント マーククリアランス 、および 世代別コレクション に基づいています。 2つの機構が補足されています。

1 参照カウント

1.1 参照カウント アルゴリズムの原理

参照カウントの原理は比較的単純です:

各オブジェクトには整数の参照カウント属性があります。 。オブジェクトが参照された回数を記録するために使用されます。たとえば、オブジェクト AA を参照する場合、A の参照カウントは 1 になります。参照が削除されると、#A の参照数は -1 になります。 A の参照カウントが 0 の場合、オブジェクト A は使用できなくなり、直接リサイクルされることを意味します。

Python では、sys モジュールの getrefcount 関数を通じて、指定されたオブジェクトの参照カウンターの値を取得できます。実際の例で見てみましょう。

import sys

class A():
    def __init__(self):
        pass
        
a = A()
print(sys.getrefcount(a))
ログイン後にコピー

上記のコードを実行すると、出力結果が

2 として得られます。

1.2 カウンタの増減条件

上記では、

A オブジェクトを作成し、そのオブジェクトを a 変数 (参照カウンタ) に代入した後を見てきました。オブジェクト 値は 2 です。それでは、カウンタが 1 になるのはいつでしょうか。また、カウンタが -1 になるのはいつでしょうか?

1.2.1 参照カウントの条件 1
A()
a=A()
func(a)
arr=[a,a]
ログイン後にコピー
1.2.2 参照カウント -1
オブジェクトが明示的に破棄される (例:

del a##) # 。変数は、a=0 などの新しいオブジェクトに再割り当てされます。オブジェクトは、func などのスコープを離れます。関数の実行が完了すると、関数内の func ローカル変数が取り出されます (グローバル変数は取り出されません)。 オブジェクトが配置されているコンテナが破棄されるか、オブジェクトがコンテナから削除されます。

1.2.3 コードの練習

カウンタの増加と減少をよりよく理解するために、実際のコードを実行して、一目でそれを明確に確認します。
import sys
 
class A():

    def __init__(self):
        pass
 
print("创建对象 0 + 1 =", sys.getrefcount(A()))

a = A()
print("创建对象并赋值 0 + 2 =", sys.getrefcount(a))

b = a
c = a
print("赋给2个变量 2 + 2 =", sys.getrefcount(a))

b = None
print("变量重新赋值 4 - 1 =", sys.getrefcount(a))

del c
print("del对象 3 - 1 =", sys.getrefcount(a))

d = [a, a, a]
print("3次加入列表 2 + 3 =", sys.getrefcount(a))


def func(c):
    print('传入函数 1 + 2 = ', sys.getrefcount(c))
func(A())
ログイン後にコピー

出力結果は次のとおりです。

创建对象 0 + 1 = 1
创建对象并赋值 0 + 2 = 2
赋给2个变量 2 + 2 = 4
变量重新赋值 4 - 1 = 3
del对象 3 - 1 = 2
3次加入列表 2 + 3 = 5
传入函数 1 + 2 =  3
ログイン後にコピー

1.3 参照カウントの利点と欠点

1.3.1 参照カウントの利点

    効率的、ロジックは単純で、ルールに従ってカウンターを加算および減算するだけです。 ############リアルタイム。オブジェクトのカウンタがゼロになると、そのオブジェクトは二度と使用できなくなり、メモリを直接解放するために特定の時間を待つ必要はなくなります。
  • 1.3.2 参照カウントの欠点
  • オブジェクトに参照カウント領域を割り当てる必要があるため、メモリ消費量が増加します。

  • 解放する必要があるオブジェクトが辞書オブジェクトなど比較的大きい場合、参照されているすべてのオブジェクトをループで呼び出してネストする必要があり、時間がかかることがあります。
循環参照。これは参照カウントの致命的な欠陥であり、参照カウントには解決策がないため、他のガベージ コレクション アルゴリズムを使用して補う必要があります。

2 Mark-Clear

前のセクションで説明したように、参照カウント アルゴリズムでは循環参照の問題を解決できません。循環参照されたオブジェクトは、カウンタが永遠に

0Python のガベージ コレクション メカニズムをマスターする方法。 に等しくないため、リサイクルできないという問題が発生します。

Mark-Clear

このアルゴリズムは主に潜在的な循環参照問題に使用され、次の 2 つのステップに分かれています:

マーキング段階。すべてのオブジェクトをグラフのノードとして扱い、オブジェクトの参照関係に基づいてグラフ構造を構築します。すべてのオブジェクトはグラフのルート ノードからトラバースされ、訪問されたすべてのオブジェクトは、オブジェクトが「到達可能」であることを示すためにマークされます。

    フェーズをクリアします。すべてのオブジェクトを走査し、「到達可能」とマークされていないオブジェクトが見つかった場合、そのオブジェクトはリサイクルされます。
  1. 具体的なコード例で説明します:
  2. class A():
        def __init__(self):
            self.obj = None
     
    def func():
        a = A()
        b = A()
        c = A()
        d = A()
    
        a.obj = b
        b.obj = a
        return [c, d]
    
    e = func()
    ログイン後にコピー

    上記のコードでは、a と b は相互に参照し、e は c と d を参照します。参照関係全体を次の図に示します。

#参照カウンタ アルゴリズムが使用される場合、2 つのオブジェクト a と b は再利用されません。マーク アンド クリア メソッドを使用すると、ルート ノード (オブジェクト e) から開始して、3 つのオブジェクト c、d、e が

reachable

としてマークされますが、a と b はマークできません。したがって、a と b はリサイクルされます。

这是读者可能会有疑问,为什么确定根节点是e,而不会是a、b、c、d呢?这里就有讲究了,什么样的对象会被看成是根节点呢?一般而言,根节点的选取包括(但不限于)如下几种:

  • 当前栈帧中的本地变量表中引用的对象,如各个线程被调用的方法堆栈中使用到的参数、 局部变量、 临时变量等。

  • 全局静态变量

  • ...

3 分代收集

3.1 分代收集原理

在执行垃圾回收过程中,程序会被暂停,即 stop-the-world 。这里很好理解:你妈妈在打扫房间的时候,肯定不允许你在房间内到处丢垃圾,要不然永远也无法打扫干净。

为了减少程序的暂停时间,采用 分代回收 ( Generational Collection )降低垃圾收集耗时。

分代回收基于这样的法则:

  1. 接大部分的对象生命周期短,大部分对象都是朝生夕灭。

  2. 经历越多次数的垃圾收集且活下来的对象,说明该对象越不可能是垃圾,应该越少去收集。

Python 中,对象一共有3种世代: G0 , G1 , G2

  1. 对象刚创建时为 G0

  2. 如果在一轮 GC 扫描中存活下来,则移至 G1 ,处于 G1 的对象被扫描次数会减少。

  3. 如果再次在扫描中活下来,则进入 G2 ,处于 G1 的对象被扫描次数将会更少。

3.2 触发GC时机

当某世代中分配的对象数量与被释放的对象之差达到某个阈值的时,将触发对该代的扫描。当某世代触发扫描时,比该世代年轻的世代也会触发扫描。

那么这个阈值是多少呢?我们可以通过代码查看或者修改,示例代码如下

import gc
threshold = gc.get_threshold()
print("各世代的阈值:", threshold)

# 设置各世代阈值
# gc.set_threshold(threshold0[, threshold1[, threshold2]])
gc.set_threshold(800, 20, 20)
ログイン後にコピー

输出结果如下:

各世代的阈值: (700, 10, 10)
ログイン後にコピー

以上が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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Google AI、開発者向けに Gemini 1.5 Pro と Gemma 2 を発表 Google AI、開発者向けに Gemini 1.5 Pro と Gemma 2 を発表 Jul 01, 2024 am 07:22 AM

Google AI は、Gemini 1.5 Pro 大規模言語モデル (LLM) を皮切りに、拡張コンテキスト ウィンドウとコスト削減機能へのアクセスを開発者に提供し始めました。以前は待機リストを通じて利用可能でしたが、完全な 200 万トークンのコンテキストウィンドウが利用可能になりました

Deepseek Xiaomiをダウンロードする方法 Deepseek Xiaomiをダウンロードする方法 Feb 19, 2025 pm 05:27 PM

Deepseek Xiaomiをダウンロードする方法は? Xiaomi App Storeで「Deepseek」を検索します。ニーズ(検索ファイル、データ分析)を特定し、DeepSeek関数を含む対応するツール(ファイルマネージャー、データ分析ソフトウェアなど)を見つけます。

どうやって彼にdeepseekに尋ねますか どうやって彼にdeepseekに尋ねますか Feb 19, 2025 pm 04:42 PM

DeepSeekを効果的に使用する鍵は、質問を明確にすることです。質問を直接および具体的に表現してください。特定の詳細と背景情報を提供します。複雑な問い合わせのために、複数の角度と反論の意見が含まれています。コードのパフォーマンスボトルネックなどの特定の側面に焦点を当てます。あなたが得る答えについて批判的な考えを維持し、あなたの専門知識に基づいて判断を下します。

DeepSeekを検索する方法 DeepSeekを検索する方法 Feb 19, 2025 pm 05:18 PM

DeepSeekに付属する検索機能を使用するだけです。ただし、不人気で最新の情報または考慮する必要がある検索の場合、キーワードを調整したり、より具体的な説明を使用したり、他のリアルタイム情報源と組み合わせたり、DeepSeekが必要なツールであることを理解する必要があります。アクティブで明確で洗練された検索戦略。

DeepSeekをプログラムする方法 DeepSeekをプログラムする方法 Feb 19, 2025 pm 05:36 PM

DeepSeekはプログラミング言語ではなく、深い検索の概念です。 DeepSeekの実装には、既存の言語に基づいて選択が必要です。さまざまなアプリケーションシナリオでは、適切な言語とアルゴリズムを選択し、機械学習技術を組み合わせる必要があります。コードの品質、保守性、テストが重要です。適切なプログラミング言語、アルゴリズム、ツールをお客様のニーズに応じて選択し、高品質のコードを作成することにより、DeepSeekを正常に実装できます。

DeepSeekを使用してアカウントを解決する方法 DeepSeekを使用してアカウントを解決する方法 Feb 19, 2025 pm 04:36 PM

質問:DeepSeekは会計に利用できますか?回答:いいえ、それは財務データの分析に使用できるデータマイニングおよび分析ツールですが、会計レコードと会計ソフトウェアの生成機能をレポートしていません。 DeepSeekを使用して財務データを分析するには、データ構造、アルゴリズム、DeepSeek APIの知識を持つデータを処理するためにコードを作成する必要があります。

コーディングの鍵: 初心者のための Python の力を解き放つ コーディングの鍵: 初心者のための Python の力を解き放つ Oct 11, 2024 pm 12:17 PM

Python は、学習の容易さと強力な機能により、初心者にとって理想的なプログラミング入門言語です。その基本は次のとおりです。 変数: データ (数値、文字列、リストなど) を保存するために使用されます。データ型: 変数内のデータの型 (整数、浮動小数点など) を定義します。演算子: 数学的な演算と比較に使用されます。制御フロー: コード実行のフロー (条件文、ループ) を制御します。

Python による問題解決: 初心者プログラマーとして強力なソリューションをアンロックする Python による問題解決: 初心者プログラマーとして強力なソリューションをアンロックする Oct 11, 2024 pm 08:58 PM

Python は、問題解決の初心者に力を与えます。ユーザーフレンドリーな構文、広範なライブラリ、変数、条件文、ループによる効率的なコード開発などの機能を備えています。データの管理からプログラム フローの制御、反復的なタスクの実行まで、Python が提供します

See all articles