ガーベッジコレクションが良いかどうかについての聖戦では、ファイルハンドルを解放するようなことは処理しないことがよくあることを指摘しています。このロジックをファイナライザに入れることは、リソースが非決定論的に解放されるため、悪いことです。しかし、OSがたくさんのファイルハンドルを用意して安価で豊富なリソースを提供できるようにすることは簡単な解決策のようであり、いつでもいくつかのリソースを無駄にする余裕があります。なぜこれは実際には行われていないのですか?ファイルがそのような高価なリソースを扱うのはなぜですか?
答えて
ファイルを閉じると、アプリケーションの視点からも、ディスクへの書き込みが消去されます。ファイルを閉じると、アプリケーション自体がクラッシュしない限り、アプリケーションがクラッシュする可能性があります。変更が失われることはありません。したがって、GCを余裕でファイルを閉じるようにするのは良い考えではありません。最近は技術的に可能かもしれませんが。
また、真実を伝えるために、古い習慣は難しいです。以前はファイルハンドルが高価でしたが、これは歴史的な理由からおそらく考えられています。
ファイルハンドルの量だけでなく、一部のモードで使用されているときに、他の呼び出し元が同じファイルにアクセスできないことがあります。
より包括的な答えが続くと確信していますが、限られた経験とWindowsの基本的な操作の理解に基づいて、ファイルハンドル(OSを表現するために使用される構造)はカーネルオブジェクトであり、特定のタイプのメモリが利用可能 - 同じリソース(すなわちファイル)へのアクセスを必要とする複数のプロセスとの一貫性と一貫性を維持するためにカーネル部分の処理はもちろん
カーネル空間のメモリを意味するならば、64ビットカーネルは現在、そして近い将来必要となる可能性のあるものと同じくらい多くのものを持っています。 –
私はそれらが必ず高価だとは思わない - あなたのアプリケーションがいくつかの不自然なものしか保持していなければ、システムを強制終了しません。ちょうどあなたがC++のいくつかの文字列だけをリークした場合、誰も気付かないでしょう。それがなるとどこに問題がある:
- ファイルのオープンを有する(他のアプリケーションが開いたり、ファイルを削除することができない場合があります) 、そのファイル上で発生するから、他の操作を妨げる場合は、数百または数千
- をリークしている場合
- あなたのプログラムが所有しているものを追跡することができず、使用している、または使用を停止している場合、プログラムには他にどんな問題がありますか?何か小さな変化やユーザーが以前とは少し違ったやり方をしたときに、小さなリークが大きなリークに変わることがあります。
リークしたファイルハンドルが正しく閉じられていないため、バッファが正しく書き込まれていない限り、もちろんありません。非常に一般的なケースでは、1つの漏れたハンドルがデバッグの悪夢になる可能性があります。 –
実際には、OSが異なるプロセスでどのハンドルが使用されているかを追跡するために、より多くのメモリオーバーヘッドを割り当てる必要があるため、実行できません。 Iは、例えば円形のキューに格納されている単純なOSプロセス構造を実証する、以下に示すように、例えばCコード...
struct ProcessRecord{ int ProcessId; CPURegs cpuRegs; TaskPointer **children; int *baseMemAddress; int sizeOfStack; int sizeOfHeap; int *baseHeapAddress; int granularity; int time; enum State{ Running, Runnable, Zombie ... }; /* ...few more fields here... */ long *fileHandles; long fileHandlesCount; }proc;
ファイルハンドルは、それぞれ整数で含ま整数の配列へのポインタであることを想像でファイルがディスク上に格納されているOSのテーブルへのオフセットの位置(おそらくエンコード形式)。
ここで、どのくらいの量のメモリが枯渇し、カーネル全体の速度を低下させる可能性があるか想像してください。システムの「マルチタスキング」という概念は、ファイルハンドルが使用中であり、OSがユーザプログラムの要求に基づいてファイルハンドルをディッシングしていた場合に、ユーザプログラムの速度を落とす際にノックオン効果を持つ可能性のある整数へのポインタを動的に増減するメカニズムを提供する。
これは、実装されていないと実用的でない理由を理解するのに役立ちます。
希望がある場合は、 をお待ちしています。 トム。
Linuxのパラダイムソケットでは、ファイル記述子です。 TCPポートをできるだけ早く開放することには明確な利点があります。
- 1. -bash:CD:リソース:そのようなファイルやディレクトリ
- 2. なぜそのようなフィールドが必要なのですか
- 3. なぜarray.lengthはそのような高い数値を返しますか?
- 4. MySQLがéをeと同じように扱うのはなぜですか?
- 5. なぜ署名鍵が高価なのですか?
- 6. なぜerase()関数が高価なのですか?
- 7. Djangoで大きなファイルを扱う(負荷が高い)
- 8. Appium:WebDriverAgent.xcodeproj:リソース/ WebDriverAgent.bundle:そのようなファイルやディレクトリは
- 9. クラスメンバーがAndroidで価値を失うのはなぜですか?
- 10. QWidget.setContentsMargins()は効果がないようです:なぜそうですか?
- 11. 最初にそれをブール値として扱うのはなぜですか?
- 12. なぜNHibernate AutoFlushは非常に高価なチェックですか?
- 13. PowerShellのベストプラクティス:高度なバッチファイルのようなPowerShellスクリプトを扱うのは悪いですか?
- 14. Java Print APIが高さよりも大きな用紙幅を扱えないのはなぜですか?
- 15. Rubyで0をTrueと扱うのはなぜですか?
- 16. なぜVSコードは.csファイルをプレーンテキストとして扱うのですか?
- 17. なぜそう
- 18. MSMQがWCF QueueServiceより高速なのはなぜですか?
- 19. rapplyとlapplyはなぜNULLを異なる方法で扱うのですか?
- 20. なぜ高次コンポーネント(HOC)がそう呼ばれるのですか?
- 21. なぜ変数が列のように扱われているのですか?
- 22. 投機的な実行は高価な操作に従うでしょうか?
- 23. RMIスタブからソケットファクトリを取得できないようです。それはなぜそうですか?
- 24. STD:そのようなファイルやディレクトリは
- 25. rsyncはそのようなファイルやディレクトリ
- 26. jenv.bash:そのようなファイルやディレクトリは
- 27. unistd:そのようなファイルやディレクトリは
- 28. OutofMemoryErrorのないグライドで高精細画像を扱うには?
- 29. 私はそのようなフォルダパスを扱うgolangでサーバましgolangサーバ
- 30. これらの変数のすべてが同じように扱われないのはなぜですか?
正確に。この問題は、ハンドルの総数が限られているのではなく、特定のファイル*に対して開くことができる排他的ハンドルの数が、* ONE *に制限されていることがよくあります。 – supercat
@supercatこれは、Windows固有の制限のように聞こえます。 – binki
@binki:特定のファイルに対してオープンできる*排他的なハンドルの数は、壊れていない実装では1に制限されます。 – supercat