問題タブ [fastmm]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
delphi - fastMMでトリッキーなメモリリークを追跡する方法は?
プロジェクトをDelphi2007からDelphi2009にアップグレードした後、不明なメモリリークが発生しました。これまで、fastMMを使用してプロジェクトを追跡しようとしてきましたが、fastMMスタックトレースのレポートは次のとおりです。
そして時々私はこれを得る:
何が実際にメモリリークを引き起こしているのかを理解するためのより良い方法はありますか?
delphi - FreeMM 対 ShareMem
Delphi と C++ ビルダーの両方で記述された dll ライブラリが多数あり、sharemem と borlndmm.dll を使用しています。
サードパーティのライブラリでアラインメントの問題が発生したため、デルファイ 2007 の新しいメモリ マネージャーに移行する必要がありました。
誰かが私のために「共有メモリマネージャー」を説明してもらえますか?
SimpleShareMem は ShareMem のドロップイン代替品ですか?
次に、borlndmm.dll の展開を停止できますか?
c++ ライブラリについても何かする必要がありますか?
一部のライブラリは ShareMem と一部の SimpleShareMem を使用できますか?
ありがとう -ベガー
delphi - Delphi で文字列に余分なメモリがあるのはなぜですか?
サイズが 24 MB (1 行あたり平均 17 文字) の 140 万行の大きなテキスト ファイルを読み込んでいます。
私は Delphi 2009 を使用しており、ファイルは ANSI ですが、読み取り時に Unicode に変換されるため、変換後のテキストのサイズは 48 MB であると言えます。
(編集:もっと簡単な例を見つけました...)
このテキストを単純な StringList にロードしています。
私は、データ行が 48 MB よりも多くのメモリを必要とするように見えることを発見しました。
実際、155 MB のメモリを使用しています。
Delphi が 48 MB または 60 MB を使用していても、メモリ管理のオーバーヘッドを考慮して問題ありません。しかし、155 MB は過剰に思えます。
これは StringList の障害ではありません。以前に行をレコード構造にロードしようとしましたが、同じ結果 (160 MB) が得られました。
Delphi または FastMM メモリ マネージャが、文字列を格納するために必要なメモリ量の 3 倍の量を使用する原因が何なのか、私にはわかりません。ヒープ割り当てはそれほど非効率的ではありませんよね?
私はこれをデバッグし、できる限り調査しました。なぜこれが起こっているのかについてのアイデア、または過剰な使用を減らすのに役立つアイデアは大歓迎です.
注: この「小さい」ファイルを例として使用しています。私は実際に 320 MB のファイルをロードしようとしていますが、Delphi は 2 GB を超える RAM を要求しており、この過剰な文字列要件のためにメモリが不足しています。
補遺: Marco Cantu が、Delphi と Unicode に関するホワイト ペーパーを発表しました。Delphi 2009 では、文字列あたりのオーバーヘッドが 8 バイトから 12 バイトに増加しました (さらに、文字列への実際のポインタの場合はさらに 4 バイト)。17x2 = 34 バイト ラインごとに 16 バイトが追加されると、ほぼ 50% が追加されます。しかし、オーバーヘッドが 200% を超えています。余分な 150% は何になるでしょうか?
成功!!皆様のご提案に感謝いたします。みなさん、考えさせられました。しかし、彼が尋ねたので、私は Jan Goyvaerts に答えを与えなければなりません:
...なぜ TStringList を使用しているのですか? ファイルは本当に別の行としてメモリに格納する必要がありますか?
その結果、24 MB のファイルを 140 万行の StringList としてロードする代わりに、プログラムが認識している自然なグループに行をグループ化できるという解決策にたどり着きました。そのため、127,000 行が文字列リストに読み込まれました。
現在、各行の平均文字数は 17 文字ではなく 190 文字です。StringList 行ごとのオーバーヘッドは同じですが、行数が大幅に少なくなりました。
これを 320 MB のファイルに適用すると、メモリが不足することはなくなり、1 GB 未満の RAM にロードされるようになりました。(そして、読み込みに約10秒しかかかりません。これはかなり良いです!)
グループ化された行を解析するために少し余分な処理が必要になりますが、各グループのリアルタイム処理では目立たないはずです。
(念のために言っておきますが、これは家系図プログラムであり、32 ビット アドレス空間に約 100 万人のすべてのデータを 30 秒以内にロードできるようにするために必要な最後のステップかもしれません。インデックスをデータに追加するための 20 秒のバッファがまだあります。これは、データの表示と編集を可能にするために必要です。)
delphi - DUnit で FastMM を使用してメモリ リークの追跡を有効にするにはどうすればよいですか?
GUI テスト ランナーでは、メモリ リーク チェックのメニュー項目が非アクティブ (グレー表示) になっています。それらをアクティブにするための、まだ見つけていない特別なスイッチはありますか?
DUnit 9.4 (Delphi 2009 または sourceforge Subversion リポジトリから) および FastMM4.92 を使用する
delphi - サービスで FastMM4 メモリ リーク レポートを使用するにはどうすればよいですか?
アプリケーションがサービスとして実行されている場合、 FastMM4 for Delphi がメモリ リークを詳細なファイルに報告するために提供するのと同じ手法は機能しますか? もちろん、ベスト プラクティスは、最初に単体テストと単純なスタンドアロン アプリケーションを作成し、サービス環境の外でリークを見つけることです。
delphi - インスタンス化されたすべてのオブジェクトをどのように一覧表示しますか?
FASTMM4またはデフォルトのメモリマネージャを使用して、すべてのアプリケーションでインスタンス化されたすべてのオブジェクトを一覧表示するにはどうすればよいですか?
delphi - FastMM4は「ブロックヘッダーが破損しています」と表示します
過去に消えたこの厄介なバグがありましたが、かなり時間が経ってから戻ってきました。
2つのTSamオブジェクト(TPersistentから派生)を作成し、TAsmJobオブジェクト(TObjectListから派生)にロードしました。
実行時に、フォームはTStringGridを作成し、次にAsmJobを作成してこれら2つのSAMオブジェクトを作成します(そして、それぞれのディスクからデータをロードします)。AsmJobもグリッドに割り当てられます。フォームが破棄されると、グリッドはAsmJobを解放することで処理し、TSamオブジェクトを解放します。問題は次のとおりです。最初のオブジェクトは問題なく解放されますが、継承されたメソッド(Destroy destructor内)が呼び出されると、2番目のオブジェクトは停止します。
プログラム全体でFreeAndNilを使用して、オブジェクトを解放します。TSamオブジェクトはNILではありません!!!!! したがって、これはオブジェクトを解放する最初の試みです。オブジェクト内のデータでさえ一貫しています。
プログラムのバックボーンは次のようになります。
オブジェクトがリリースされた後、どこでオブジェクトをダブルフリーまたは上書きしようとしているのか、本当にわかりません。
編集:
私が得たエラーのいくつか:
FastMMは、フリーブロックスキャン操作中にエラーを検出しました。FastMMは、ブロックが解放された後に変更されたことを検出しました。
FastMMは、フリーブロックスキャン操作中にエラーを検出しました。ブロックヘッダーが破損しています。
詳細:
「範囲チェック」を含め、IDEですべての「デバッグ」オプションを有効にしています。また、FastMM4はスーパーアグレッシブデバッグモードに設定されています。FastMMがなくても、デバッガーの外でも、プログラムは問題なく実行されますが、バグがなくなったわけではありません。FastMMをインストールするまで、実際には(おそらく)1年以上機能していました。
編集:
みなさん、ありがとうございました。いいえ、私は少し良い方向に進んでいると感じています。
プログラムの構造はもっと複雑です。元の投稿を小さく保つためにバックボーンのみを提供しました。しかし、一体、それはすでに大きくなっています:)したがって、これらのTSamオブジェクトは、ディスクからデータをロードするために使用されます。各オブジェクトに1つのファイル。彼らはまた、いくつかの処理とデータ検証を行っています。これらのTSamのそれぞれについて、TSamオブジェクトに含まれるデータを画面に(グラフィカルに)表示するグラフィカルオブジェクトもあります。TStringGridの各行には、TSamのデータも表示されますが、テキストで表示されます。
私が持っている1つの質問:エラーがどこにあるかを見つけるためにプログラムを細かく分割しても、エラーはまだ表示されますか?または、この特定の構成でのみ表示することは可能ですか?
「TStringGridがAsmJobを破棄するように、AsmJobはどのようにTStringGridに割り当てられますか?」に対する回答。
次に、TForm.Create(グリッドを保持するフォーム)のどこかで、
MyGridのデストラクタでは、次のようにします。
delphi - FastMMからスタックトレースを取得する方法
次の投稿で、FastMMからスタックトレースを取得して、オブジェクトが割り当てられた場所に表示されるものを表示できることに気付きました。
ただし、Delphi2009でこれを有効にする方法に関する情報は見つかりません。
trueに設定ReportMemoryLeaksOnShutdown
したので、基本レポートを取得しますが、スタックトレースレポートを取得するにはどうすればよいですか?
delphi - Delphi-構造体の文字列が解放されない[FastMMマネージャー]
私が宣言した場合
そして私は次のコードを実行します:
FastMM 4メモリマネージャは、メモリリークが発生したことを報告します(タイプ:文字列、データダンプ: "something bla bla bla")。ただし、呼び出す前にs1文字列を空に設定しても問題ありませんdispose
。
私が見つけた2番目の方法は、レコードタイプからクラスに変更するnew
ことです。次に、インスタンスを作成する代わりに、dispose
を呼び出す代わりにinstance.Free()
。弦を手動で掃除しなくても機能します。
電話をかけたときにDelphiで文字列を自動的にクリーンアップする方法はありますdispose
か?