3

DelphiXEでのサードパーティコンポーネントのスレッドコードの処理方法で問題が発生しています。私たちのコアアプリケーションはそれ自体でマルチスレッドコードを実装していないため、サードパーティと言います。SimpleShareMem(メインアプリと文字列データを共有するdllがいくつかあります)を使用すると奇妙なメモリ破損が発生することがわかりましたが、FastMM4ユニットをインストールするとこれらのエラーは消えます。そして奇妙なことに、エラーは同じ一般的な領域にありますが、2回続けて同じになることはめったにありません。最初にFastMM4をインストールしてエラーの原因を特定しようとしましたが、実際には、インストール時に発生しません。オプションセットに条件を設定して、プロジェクトグループ内のすべてのモジュールをSimpleShareMemとFastMMの間で切り替えられるようにしました。

私の直接の例はTRichViewです。hunspellスペルチェッカーを使用すると、PaintBuffered / PaintToプロシージャ内またはその近くで、貼り付けと上向きのクリックスクロールを何度も同時に行うことでエラーが発生する可能性があることがわかりました(必要な回数は異なります)。これを実行してエラーを生成します)。表面化された例外に解決されるのは外部例外である場合もあれば、例外処理コード内でスタックオーバーフローに到達する場合もあります。

私が遭遇した別の例は、AnyDAC(DA-SOFT)リモート/ファイル監視システムです。これも別のスレッドで実行され、SimpleShareMemでは機能しませんが、FastMM4では正常に機能します。

これらの経験に基づいて、私は本番ビルドにFastMM4ユニットを使用してビルドすることを余儀なくされています。もちろん、私は常に自分のコードを最初に疑うので、FastMM4はメインアプリにスタックの破損などがあるとは表示しませんが、問題を悪化させるために何かできることがあるかどうか疑問に思っています。

だから、私の質問は、Delphi XEが使用しているFastMMのどのバージョンよりも、FastMM4がマルチスレッド操作でうまく機能する理由を誰かが考えることができますか?

更新:古いSharemem / borlndmm.dllの概念を使用していくつかのテストを行ったので、それも問題なく機能することを追加したいと思います。

アップデート2:提案ありがとうございます。私は自分の問題を引き起こしている特異なバグを見つけようとしてきましたが、ほとんど成功していません。私は追加の観察を持っています。

ShareMemを必要とするDLLがロードされないようにメインアプリを変更した場合、使用しているメモリマネージャーに関係なく、AnyDACロギングまたはTRichViewのいずれにも問題はありません。そのDLL(FastMMの初期インスタンスを起動し、メインアプリと共有される)をロードするという行為自体が、そのdllを呼び出さなくても問題を引き起こします。次に行うことは、メインアプリを変更して、そのdllの動的ロードを有効にし(したがって、メモリマネージャーをメインアプリに強制的にインストールする)、それが違いを生むかどうかを確認することです。

更新3: dllを動的にロードすると、ロードしないのと同じ効果があります...すべてが機能します。

4

1 に答える 1

5

Delphi XE に組み込まれているメモリ マネージャは、FastMM4 の縮小バージョンです。

メモリ ブロック アロケータ自体は同じですが、共有メカニズムは同じではありません。

デフォルトでは、次の条件が に設定されていFastMM4Options.incます。

{Define this to enable backward compatibility for the memory manager sharing
 mechanism used by Delphi 2006 and 2007, as well as older FastMM versions.}
{$define EnableBackwardCompatibleMMSharing}

ライブラリが共有メモリ マネージャ インスタンスを取得するための非表示のウィンドウ ハンドルを作成します。これは、Delphi 2006 および 2007 での動作と同じです。

この種の共有は、Delphi 2009 以降に実装されている FastMM4 のカットダウン バージョンには存在しませんGetMem.inc。これは、共有メモリ マネージャー ファイル マッピング (新しい方法) のみを実装します。ライブラリの 1 つは古いバージョンのメモリ マネージャ共有を必要とする場合があり、共有メモリ マネージャ インスタンスを見つけることができないため、独自のメモリ アロケータを使用し、共有メモリ (stringインスタンスなど) の処理に失敗します。

これが 2 つのバージョン間で私が見つけた唯一の違いであり、プログラムで共有が期待どおりに機能しない理由である可能性があります。Delphi 2006 または 2007 でコンパイルされたいくつかのライブラリがあり、共有方法は Embarcadero によって廃止されました (コードのバイト数を節約するため?)。

于 2011-11-04T17:54:32.833 に答える