一般的に、 Python では、メモリ リークの問題を解決するために、オブジェクトの参照カウントが使用され、参照カウントに基づいて自動ガベージ コレクションが実装されます。
Python には自動ガベージ コレクションがあるため、多くの初心者は、それ以来良い生活を送っており、メモリ リークに悩まされる必要がなくなったと誤解しています。しかし、Python ドキュメントの __del__() 関数の説明を注意深く見ると、このような好景気にも雲があることがわかります。以下はドキュメントからの抜粋です:
オブジェクトの参照カウントがゼロになるのを妨げる一般的な状況としては、次のようなものがあります。オブジェクト間の循環参照 (例: オブジェクトへの参照が二重にリンクされたリストや、親ポインターと子ポインターを持つツリー データ構造)。例外をキャッチした関数のスタック フレーム上 (sys.exc_traceback に保存されたトレースバックにより、スタック フレームが維持されます)、または対話モードで未処理の例外を発生させたスタック フレーム上のオブジェクトへの参照 (sys.exc_traceback に保存されたトレースバック)。 .last_traceback はスタック フレームを維持します)。
__del__() 関数によるオブジェクト間の循環参照がメモリ リークの主な原因であることがわかります。
さらに、__del__() 関数を使用しない Python オブジェクト間の循環参照は、自動的にガベージ コレクションされる可能性があります 。
オブジェクトにメモリ リークがあるかどうかを確認するにはどうすればよいですか?
方法 1. オブジェクトを破棄する必要があると思われる場合 (つまり、参照カウントが 0 である場合)、sys.getrefcount(obj) を通じてオブジェクトの参照カウントを取得し、メモリ リークがあるかどうかを判断できます。戻り値が 0 かどうかに基づきます。返された参照カウントが 0 でない場合は、現時点ではオブジェクト obj をガベージ コレクターでリサイクルできないことを意味します。
方法 2: Python 拡張モジュール gc を使用して、リサイクルできないオブジェクトの詳細情報を表示することもできます。
まず、通常のテストコードを見てみましょう:
#--------------- code begin -------------- # -*- coding: utf-8 -*- import gc import sys class CGcLeak(object): def __init__(self): self._text = '#'*10 def __del__(self): pass def make_circle_ref(): _gcleak = CGcLeak() # _gcleak._self = _gcleak # test_code_1 print '_gcleak ref count0:%d' % sys.getrefcount(_gcleak) del _gcleak try: print '_gcleak ref count1:%d' % sys.getrefcount(_gcleak) except UnboundLocalError: print '_gcleak is invalid!' def test_gcleak(): # Enable automatic garbage collection. gc.enable() # Set the garbage collection debugging flags. gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | / gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS) print 'begin leak test...' make_circle_ref() print 'begin collect...' _unreachable = gc.collect() print 'unreachable object num:%d' % _unreachable print 'garbage object num:%d' % len(gc.garbage) if __name__ == '__main__': test_gcleak()
test_gcleak() では、ガベージ コレクターのデバッグ フラグを設定した後、collect() を使用してガベージ コレクションを実行し、最後に、このガベージ コレクションで見つかった到達不能なガベージ オブジェクトの数とインタープリター全体のガベージ オブジェクトの数を出力します。 。
gc.garbage はリスト オブジェクトです。リスト項目は、ガベージ コレクターによって到達不能であることが検出されたものの、解放できない (つまり、リサイクルできない) オブジェクトです。ドキュメントの説明は次のとおりです: コレクターが到達不能であることが判明したが解放できなかったオブジェクト (収集不可能なオブジェクト) のリスト。
通常、gc.garbage 内のオブジェクトは参照リング内のオブジェクトです。 Python は、リング内のオブジェクトの __del__() 関数をどのような安全な順序で呼び出すことができるかわからないため、オブジェクトは常に gc.garbage 内に存在し、メモリ リークが発生します。安全な順序がわかっている場合は、参照サイクルを中断し、del gc.garbage[:] を実行してガベージ オブジェクト リストをクリアします。
上記のコードの出力は次のとおりです (# の後の文字列は作成者が追加したコメントです):
#----------------------------------------- begin leak test... # 变量 _gcleak 的引用计数为 2. _gcleak ref count0:2 # _gcleak 变为不可达(unreachable)的非法变量. _gcleak is invalid! # 开始垃圾回收 begin collect... # 本次垃圾回收发现的不可达的垃圾对象数为 0. unreachable object num:0 # 整个解释器中的垃圾对象数为 0. garbage object num:0 #-----------------------------------------
_gcleak オブジェクトの参照カウントが正しく、どのオブジェクトでもメモリ リークが発生していないことがわかります。
make_circle_ref() の test_code_1 ステートメントをコメントアウトしない場合:
_gcleak._self = _gcleak
つまり、_gcleak がそれ自体への循環参照を形成するようにします。上記のコードを再度実行すると、出力は次のようになります:
#----------------------------------------- begin leak test... _gcleak ref count0:3 _gcleak is invalid! begin collect... # 发现可以回收的垃圾对象: 地址为 012AA090,类型为 CGcLeak. gc: uncollectable <CGcLeak 012AA090> gc: uncollectable <dict 012AC1E0> unreachable object num:2 #!! 不能回收的垃圾对象数为 1,导致内存泄漏! garbage object num:1 #-----------------------------------------
Visible
{'_self': <__main__.CGcLeak object at 0x012AA090>, '_text': '##########'}それ自体への循環参照に加えて、複数のオブジェクト間の循環参照もメモリ リークを引き起こす可能性があります。簡単な例は次のとおりです:
#--------------- code begin -------------- class CGcLeakA(object): def __init__(self): self._text = '#'*10 def __del__(self): pass class CGcLeakB(object): def __init__(self): self._text = '*'*10 def __del__(self): pass def make_circle_ref(): _a = CGcLeakA() _b = CGcLeakB() _a._b = _b # test_code_2 _b._a = _a # test_code_3 print 'ref count0:a=%d b=%d' % / (sys.getrefcount(_a), sys.getrefcount(_b)) # _b._a = None # test_code_4 del _a del _b try: print 'ref count1:a=%d' % sys.getrefcount(_a) except UnboundLocalError: print '_a is invalid!' try: print 'ref count2:b=%d' % sys.getrefcount(_b) except UnboundLocalError: print '_b is invalid!' #--------------- code end ----------------このテスト後の出力結果は次のとおりです:
#----------------------------------------- begin leak test... ref count0:a=3 b=3 _a is invalid! _b is invalid! begin collect... gc: uncollectable <CGcLeakA 012AA110> gc: uncollectable <CGcLeakB 012AA0B0> gc: uncollectable <dict 012AC1E0> gc: uncollectable <dict 012AC0C0> unreachable object num:4 garbage object num:2 #-----------------------------------------_a オブジェクトと _b オブジェクトの両方でメモリ リークが発生していることがわかります。この 2 つは循環参照であるため、ガベージ コレクターはそれらをリサイクルする方法がわかりません。つまり、どのオブジェクトの __del__() 関数を最初に呼び出すべきかがわかりません。
メモリ リークを避けるために、次のいずれかの方法を使用して循環参照を解除します。
1. make_circle_ref() の test_code_2 ステートメントをコメント化します。
2. make_circle_ref() の test_code_3 ステートメントをコメント化します。
3. make_circle_ref() 内の test_code_4 ステートメントのコメントを解除します。
対応する出力結果は次のようになります:
#----------------------------------------- begin leak test... ref count0:a=2 b=3 # 注:此处输出结果视情况变化. _a is invalid! _b is invalid! begin collect... unreachable object num:0 garbage object num:0 #-----------------------------------------結論: Python の gc には比較的強力な機能があり、たとえば gc.set_debug(gc.DEBUG_LEAK) を設定すると、循環参照によるメモリ リークをチェックできます。開発中にメモリ リーク チェックを実行し、公開時にメモリ リークがないことを確認すると、Python のガベージ コレクション間隔を延長したり、ガベージ コレクション メカニズムを積極的にオフにしたりすることができるため、操作効率が向上します。

Pythonは、データサイエンス、Web開発、自動化タスクに適していますが、Cはシステムプログラミング、ゲーム開発、組み込みシステムに適しています。 Pythonは、そのシンプルさと強力なエコシステムで知られていますが、Cは高性能および基礎となる制御機能で知られています。

2時間以内にPythonの基本的なプログラミングの概念とスキルを学ぶことができます。 1.変数とデータ型、2。マスターコントロールフロー(条件付きステートメントとループ)、3。機能の定義と使用を理解する4。

Pythonは、Web開発、データサイエンス、機械学習、自動化、スクリプトの分野で広く使用されています。 1)Web開発では、DjangoおよびFlask Frameworksが開発プロセスを簡素化します。 2)データサイエンスと機械学習の分野では、Numpy、Pandas、Scikit-Learn、Tensorflowライブラリが強力なサポートを提供します。 3)自動化とスクリプトの観点から、Pythonは自動テストやシステム管理などのタスクに適しています。

2時間以内にPythonの基本を学ぶことができます。 1。変数とデータ型を学習します。2。ステートメントやループの場合などのマスター制御構造、3。関数の定義と使用を理解します。これらは、簡単なPythonプログラムの作成を開始するのに役立ちます。

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...

fiddlereveryversings for the-middleの測定値を使用するときに検出されないようにする方法

Python 3.6のピクルスファイルのロードレポートエラー:modulenotFounderror:nomodulenamed ...

風光明媚なスポットコメント分析におけるJieba Wordセグメンテーションの問題を解決する方法は?風光明媚なスポットコメントと分析を行っているとき、私たちはしばしばJieba Wordセグメンテーションツールを使用してテキストを処理します...


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。
