問題タブ [nio]
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.
java - Bytebuffers と NIO を使用しているときに OutOfMemoryError を回避するにはどうすればよいですか?
ByteBuffers
およびを使用しFileChannels
て、バイナリ データをファイルに書き込みます。大きなファイルに対して、または複数のファイルに対して連続してそれを行うと、OutOfMemoryError
例外が発生します。Bytebuffers
NIO での使用は壊れており、避けるべきであることを他の場所で読みました。すでにこの種の問題に直面していて、大量のバイナリ データを Java のファイルに効率的に保存するための解決策を見つけた人はいますか?
jvm オプションを使用-XX:MaxDirectMemorySize
する方法はありますか?
java - なぜSocketChannelの書き込みは、非ブロッキングソケットでも常に全量が完了するのですか?
WindowsでSunJavaVM 1.5または1.6を使用して、ノンブロッキングソケットを接続します。次に、ByteBuffer
出力するメッセージをaに入力write()
し、SocketChannelに送信しようとします。
書き込まれる量がソケットのTCP出力バッファーのスペースの量よりも大きい場合、書き込みは部分的にしか完了しないと思います(これは直感的に期待できることであり、ドキュメントについての私の理解でもあります)が、そうではありません起こります。数メガバイトであっても、write()
常に書き込まれた全量を報告するように見えます(ソケットのSO_SNDBUFは8KBで、私の数メガバイトの出力メッセージよりはるかに少ないです)。
ここでの問題は、出力が部分的に書き込まれる場合(WRITE
セレクターにインタレストセットを登録しselect()
、残りが書き込まれるまで待機する)を処理するコードをテストできないことです。起こる。何がわからないの?
java - Java: Object(In|Out)putStreams を介してブロッキング SocketChannel で同時読み取りと書き込みが可能ですか?
ブロッキングでObjectInputSteam
andを作成し、同時に読み書きしようとしています。私のコードは次のようなものです:ObjectOutputStream
SocketChannel
問題は、行 (A) での読み取りが完了するまで、行 (B) での書き込みがブロックされることです (によって返されるオブジェクトのブロックSelectableChannel#blockingLock()
)。しかし、アプリのロジックは、すべての書き込みが完了するまで読み取りが完了しないように指示するため、実質的なデッドロックが発生します。
SocketChannel
javadocs によると、同時読み取りと書き込みがサポートされています。
通常の Socket ソリューションを試したとき、そのような問題は発生しませんでした。
ただし、パフォーマンス上の利点を利用することはできませんFileChannel#transferTo(...)
java - Java NIO select() は選択されたキーなしで返されます - なぜですか?
いくつかのテスト コードを書いているときに、Selector.select() が Selector.selectedKeys() に処理するキーが含まれていなくても返されることがあることがわかりました。これは、accept() されたチャネルを登録すると、タイトなループで発生しています。
関心のある操作として。
ドキュメントによると、select() は次の場合に返されます。
1) 行動できるチャネルがある。
2) 明示的に Selector.wakeup() を呼び出します - キーが選択されていません。
3) select() を実行しているスレッドを明示的に Thread.interrupt() します - キーは選択されません。
select() の後にキーを取得しない場合は、ケース (2) と (3) に該当する必要があります。ただし、私のコードは、これらのリターンを開始するために wakeup() または interrupt() を呼び出していません。
この動作の原因についてのアイデアはありますか?
java - java.net と java.nio の比較
どの時点で java.net から java.nio に切り替えるのがよいでしょうか? .net (Microsoft エンティティではない) は理解しやすく親しみやすいのに対し、nio はスケーラブルであり、いくつかの気の利いた機能を備えています。
具体的には、この状況に対して選択を行う必要があります。複数のリモート サイトでハードウェアを管理する 1 つのコントロール センターがあります (各サイトには、複数のハードウェア ユニット (トランシーバ、TNC、およびローテータ) を管理する 1 台のコンピュータがあります)。私のアイデアは、コントロール センターから無線ハードウェアへのゲートウェイとして機能するサーバー アプリを各マシンに作成し、各ユニットに 1 つのソケットを用意することでした。私の理解では、NIO は 1 つのサーバー、多数のクライアントを対象としていますが、私が考えているのは 1 つのクライアント、多数のサーバーです。
3 番目のオプションは MINA を使用することだと思いますが、それが単純な問題を投げかけすぎているかどうかはわかりません。
各リモート サーバーには、すべて同じクライアントからの最大 8 つの接続があります (すべてのハードウェアを制御し、TX/RX ソケットを分離するため)。ただし、単一のクライアントは一度に複数のサーバーに接続する必要があります。各サーバーを異なるポートに配置する代わりに、クライアント側でチャネルセレクターを使用することは可能ですか、それともクライアント側でマルチスレッド io を使用してサーバーを別の方法で構成する方がよいでしょうか?
実際、リモート マシンは他のハードウェアと対話するためだけに機能するため、RMI または IDL/CORBA のほうが優れたソリューションでしょうか? 本当に、コマンドを送信してハードウェアからテレメトリを受信できるようにしたいだけで、アプリケーション層プロトコルを作成する必要はありません。
java - nio を使用すると、serverSocket.accept() が IllegalBlockingModeException をスローします。
次のようにコーディングすると:
メソッドはServerSocket.accept()
をスローしjava.nio.channels.IllegalBlockingModeException
ます。accept()
ブロッキングを に設定しているのに、を呼び出せないのはなぜfalse
ですか?
java - Selector.wakeup 呼び出しを検出する方法
私が書くなら:
モーニングコールを正しく検出しますか?
背景情報:
ほとんどの場合、パケットを受信してファイルに保存するサーバーを作成しています。アプリケーションが自分自身に特別なパケットを送信する必要があることはほとんどありません。このために、(別のスレッドから) サーバーソケットへの接続を開始します。
問題は、メインスレッドがすでに Selector.select() にある場合、SelectableChannel.register() がブロックされる可能性があることです。これが起こらないようにするために、私は Selector.wakeup() を呼び出しています。これにより、メイン スレッドが select() から途中で戻ります。他のスレッドが登録呼び出しを完了する機会があることを確認するには、メイン スレッドを同期する必要がありますが、select() から戻るたびにそれを行う必要があります。wakeup() 呼び出しのために select() から返されたかどうかを検出できれば、この場合に最適化できます。
したがって、理論的にはトップ コード スニペットは機能するはずですが、特定されていない動作に依存しているため、機能するだけなのかどうか疑問に思っていました。
ヒントをありがとう。
java - 桟橋でNIOとBIOを使用する利点は?
(100ms-900ms) の範囲の実行時間ですべてのクエリに対してヒープと計算集約型のプロセスを実行する場合の nio と bio のトレードオフに関する経験はありますか?
java - Java の FileLock を使用する場合、close() で自動的に lock.release() を実行しても問題ありませんか?
ほとんどの人が知っているclose()
ように、ストリームが使用するものも閉じます。
これにより、次のコードが可能になります。
FileInputStream
への参照を必要とせず、閉じることを忘れないので、これは素晴らしいことです。
しかし、それはsでも機能しFileLock
ますか?
このコードを試してみたところ、br.close()
が呼び出されたときにロックが正しく解放されましたが、そうしても安全ですか? Closeable JavaDocは、「このストリームを閉じて、それに関連付けられているシステム リソースをすべて解放します」と述べています。ロックclose()
に指定されたとおり に使用していると想定しても安全ですか?release()
java - Java NIO:大きなメッセージをすばやく送信すると、パケットが切り捨てられ、データが失われます
Java(NIO)サーバー(Linuxを実行している)からクライアントに複数の大きなメッセージをすばやく連続して送信すると、パケットが切り捨てられるという厄介な問題があります。問題が発生するには、メッセージが大きく、非常に迅速に送信される必要があります。これが基本的に私のコードが行っていることです(実際のコードではありませんが、多かれ少なかれ何が起こっているのか):
したがって、パケットが十分に長く、可能な限り迅速に送信される場合(つまり、遅延のないこのようなループで)、もう一方の端では、次のような結果になることがよくあります。
データが失われ、パケットが一緒に実行され始めます。そのため、パケット5の開始(この例では)は、パケット4の開始と同じメッセージで到着します。切り捨てるだけでなく、メッセージを一緒に実行します。
これはTCPバッファまたは「ウィンドウサイズ」に関連していると思います。または、ここのサーバーは、OSやネットワークアダプタなどが処理できるよりも高速にデータを提供しているだけだと思います。しかし、どうすればそれをチェックして、それが起こらないようにすることができますか?sc.write()を使用するたびにメッセージの長さを減らしても、繰り返しを増やしても、同じ問題が発生します。短時間でのデータ量の問題に過ぎないようです。sc.write()が例外をスローしていることもわかりません(上記の例ではチェックしていませんが、テストにはあります)。
プログラムでデータの準備ができていないかどうかをプログラムで確認し、遅延を入れて、準備ができるまで待つことができれば幸いです。「sc.socket()。setSendBufferSize(1024 * 1024);」かどうかもわかりません。何らかの効果があります。または、Linux側でこれを調整する必要がある場合。SocketChannelを実際に「フラッシュ」する方法はありますか?不十分な回避策として、たとえば10KBを超えるメッセージを送信しようとしているときはいつでも、バッファリングされているものを明示的に完全に送信しようとすることができます(これは私のアプリケーションではそれほど頻繁ではありません)。しかし、バッファの送信を強制する(または送信されるまで待つ)方法はわかりません。助けてくれてありがとう!