5

既存のJavaコードベースからすべてのシステムコールを削除するように取り組んでいます。アプリケーションは、市販のクローズドソースのJVMで実行します。JVMがgetRuntime.exec()javaを介してシステムコールを行うと、JVMプロセスフォーク全体が呼び出され、パフォーマンスが大幅に低下します。私たちはLinuxプラットフォームで実行していますが、理想的には可能な限り移植性を維持するように努めています。

getRuntime.exec()メソッドを介して現在使用しているsync()呼び出しを置き換える際に問題が発生しています。このsync()メソッドとflush()もあることを私は知っています。そして、この投稿に基づいて、開いているすべてのファイルストリームと同期してフラッシュすることを検討しています。

私の問題は、そこにあるファイルストリームと記述子について直接の知識がないことです。これを回避する1つの方法は、/ proc /(jvmプロセス番号)/ fdフォルダーを確認することだと思いましたが、純粋なJavaを使用してJVMプロセス番号を確実に取得するための良い方法を見つけることができません。特定のクラス(FileDescriptorクラス)のすべてのオブジェクトを取得できる可能性があると思いましたが、私が読んでいることから、これも実行可能ではありません。

純粋なJavaで*nixsync()呼び出しを複製する方法について誰かが提案を持っていますか?

4

1 に答える 1

4

あなたがしていることは単なるsync呼びかけではありません。「すべてのファイルバッファをフラッシュする」操作を実行しようとしていますsync。C /C++でもこれを行うのは難しいでしょう。

開いているすべてのファイルを見つけるという問題(おそらく解決できるかもしれません...)に加えて、より大きな問題があります。つまり、バッファをフラッシュするのに適切なタイミングであるかどうか。

アプリケーションがマルチスレッドであり、1つのスレッドがの呼び出しを担当していると仮定しましょうsync。そのスレッドは、ファイルを書き込んでいる他のスレッドがファイルに対して一貫したポイントに到達したことをどのようにして知るのでしょうか。つまり、アプリケーションが強制終了されて再起動された場合、(仮想的に)フラッシュされたファイルには、アプリケーションの論理的に一貫した状態が含まれますか?答えは(おそらく)それが知らないということです。つまり...実際には...同期する前にフラッシュした場合、アプリケーションはそれほど良い位置にありません。

そして、さらに別の問題があります。スレッドAがフラッシュ/同期を担当し、スレッドBが出力ストリームに正常に書き込みを行っていると仮定します。この時系列を考えてみましょう。

  1. スレッドAはファイルをフラッシュします
  2. スレッドBはファイルに書き込みます
  3. スレッドAは同期を呼び出します

これを回避する唯一の方法は、スレッドAを同期させ、ファイルに書き込んでいる他のすべてのスレッドをブロックしてから、フラッシュと同期を実行することです

私のアドバイスは、同期を行うだけで、フラッシュを忘れることです。一貫性のないファイルの問題に対処するには、従来の方法(アプリケーションに一時ファイルへの書き込みを行わせ、アトミックな名前変更を行う)、またはファイルを書き込むスレッドと同期スレッドを調整させる...重要なファイルに一貫性がある場合にのみ「同期」します。

于 2012-11-12T23:10:06.863 に答える