Windows 10 Creators Update が2か月前にリリースされてから、ランタイムパッケージに関する問題、主にアプリケーションのデバッグ中の問題がが報告されてきました。
(例えば、https://quality.embarcadero.com/browse/RSP-17972、私(Marco)とEmbarcaderoのサポートとR&Dが協力してくれました)
 この問題は、単一の実行可能ファイルとしてコンパイルされたアプリケーションではなく、ランタイムパッケージ(BPL)を使用するアプリケーションが影響を受けます。
一般的に言えば、この問題はDelphiのすべてのバージョン(最新、古い、またはそれ以前のもの)でビルドされた、ランタイムパッケージを使用するすべてのアプリケーションが影響を受けます。
ほどんど場合において、エンドユーザーアプリケーションにおいて速度低下は限定的ですが、しかしながら、ネットワーク共有しているランタイムパッケージを適用したアプリケーションには影響があります。
しかしいったい何が起こっていたのでしょうか? 

 

問題の核心:DLLローディングの最適化

まずはバッググラウンド情報から。
Windowsオペレーティングシステムでは、動的リンク(DLL)は、ロード時のバインディングと、完全実行時バインディング(LoadLibrary)の両方をサポートしています。
どちらの場合も、DLLが生成されると、エントリポイントのテーブル(エクスポートテーブル)を持ちます。
他のライブラリや実行ファイルは そのエクスポートテーブルのファンクションを参照するインポートテーブルを持っています。
初期の時代から、Delphiコンパイラ(およびリンカ)は複数のユニットを1つのバイナリファイルにアセンブルしてDLL、またはパッケージライブラリ(BPL)を生成した時に、エクスポート/インポートテーブルに複数のセクションを作成することで、関数とメソッドを利用できるようにしています。
これはおそらくマイナーなリンカの最適化で、そして今までサイドエフェクトを引き起こしませんでした。

Windows 10 Creators Update に話を戻しましょう。

Microsoftでは、アプリケーションのローディングを最適化するためにDLLローディングのコードを並列化するように書き直すことにしました。  (異なるスレッドは異なるライブラリを並行して読み込むことができます)
しかし、この変更は、エクスポートテーブルに複数のセクションがあるライブラリのローディングに影響を及ぼしました。
経験的に言って、BPLが各セグメントに対して一度にロードされているようです。
DelphiのBPLコア(rtl、vcl、fmx)の大部分には、何十ものセクションがあるため、結果として、ライブラリがロードされ(そしてアンロードされ)ることが何十回も繰り返し実行されているものと考えられます。

これは そのエフェクトのイベントログのスクリーンショットです。(これはシングルフォームのFireMonkeyアプリケーションです):

私のマシン上のこの単純なアプリケーションでは、数秒遅くなっているだけですが、多くのランタイムパッケージを持つより大きいアプリケーションでは、デバッガへの影響はかなり大きなものになる可能性があります。

これはフルデバッガーのログで、パッケージの操作に関すもの(とその他注目すべきもの)を強調表示(太字)にしています:

[crayon-673a9c416f6e9778609634/]

繰り返しますが、 この問題はオペレーティングシステムレベルの変更により発生しているもののため、Delphi 10.2 TokyoまたはDelphi 10.1 Berlinに固有のものではなく、同じことがXEシリーズや製品のクラシックバージョンにも当てはまります。

RAD Studioを使用している開発者に対し、我々は開発用マシンでWindows 10 Creators Updateに移行することはお勧めしないものの、これでは解決策になりません。さらには最新のWindowsバージョンを試す妨げにもなります。

 

第一の解決: エンバカデロがリンカを修正する

問題は、ランタイムパッケージがオペレーティングシステムによってどのようにマネージされるかということなので、最終的なソリューションは2人のプレイヤー[エンバカデロまたはマイクロソフト]からのみ得られることになります。

事実、それは両サイドから来ています。

エンバカデロ側では、必要なすべてのエントリを含む単一のインポートテーブルが作成されるよう、我々、R&Dチームは10.2 Tokyoのリンカの変更に取り組んでいます。
問題としては、新しいリンカーをリリースしたばかりで、すべての既存のパッケージライブラリに未だ不具合があります。
したがって、製品のかなりの部分を更新する必要があり、一般的に、これは、ホットフィクスではなく、アップデート(または新しいリリース)でなされます。これは決して最終的な決定ではなく、R&DとPMは代替案をより重要視しています。
一方、より古いDelphiのバージョンではどうなるでしょう?
再コンパイルが必要なパッケージ(我々とサードパーティ)への影響を考えると、これは、RAD Studioの以前のバージョンに対処するのは非常に難しいシナリオです。

 

第2の解決法: MicrosoftがLoadを修正する

2番目の解決策は、Microsofotによってロード問題が対処され、最適化された並列ロードを維持しながら、Delphiパッケージのシナリオを考慮に入れることです。(実際には、限られた範囲の少数のプラットフォームライブラリでも発生します)。
今、私たちはMicrosoftとこの問題について関わっているという事実をシェアできて非常に嬉しく、彼らはそれにとても早く取り組んでいます。
Windows 10 Fall Creators Updateの最新16215「Insider Build」がこの問題に対処しています。
https://blogs.windows.com/windowsexperience/2017/06/08/announcing-windows-10-insider-preview-build-16215-pc-build-15222-mobile

ご覧のとおり、10.2 TokyoのRTM版(訳者注:とWindows 10 Fall Creators Updateの最新16215「Insider Build」)を使用すると、FMXライブラリが2回読み込まれます。 実際に問題を起こすことはありませんでした:

こちらは、ビルド16215でランタイムパッケージを使用してWindows FireMonkeyアプリケーションのデバッグを開始したときのフルイベントログです。Delphiパッケージに関連する行は太字で示しています:

[crayon-673a9c416f6f3179208586/]

完璧な解決策ではないですか? 
ですが、Delphiの現在のバージョンとオールドバージョン両面で修正されているものの、残念ながらすぐには解決されません。
Microsoftが問題を解決したことは間違いありませんが、ソリューションが次のメジャーリリースのオペレーティングシステムのみで提供され、それが数か月後(秋のCretors Update)なら、開発者とユーザーはどうなるでしょう?
私たちは依然としてMicrosoftにWindowsの現在のバージョンについても修正をリクエストしており、あなたもこのリクエストに乗ることができます。

 

いくつかの一時的なワークアラウンド

上記の2つのソリューションが提示されていますが、すぐに問題を解決するわけではないので、開発者にとって、いくつかの回避策にフォーカスすることが重要です。

 

第一のワークアラウンドは、デバッギングです。アプリケーションのロード時にその問題が発生した場合、スタンドアロンで実行し、後でデバッガをアプリケーションに接続するということが、ほとんどの開発者にとって有効なようです。
これは確かに、煩わしいことですが、長い時間を待たされたり、デバッガがスタックするよりは良いでしょう。

第二のワークアラウンド(エンドユーザー向け)は、インポート/エクスポートテーブルの再編成を含む、PEの実行可能ファイルを修正し、クリーンアップするツールを検討することです。そのようなツールはたくさんあります。
その一つが: http://www.ntcore.com/exsuite.php.

もちろん、Windows 10 Anniversaryエディションに留まる事も、また、最新のInsiderリリースにジャンプしたり、ランタイムパッケージの使用から単一の実行可能ファイルのリリースに移行するなど、その他のエクストリームなオプションもあります。

 

結論

私たちはこの問題に対処する リンカソリューションをリリースするために取り組んでいます。
マイクロソフトには広範かつ即時の修正を求め続けており、短期的な代替回避策も検討しています。
さらなる詳細情報をお待ちください。