问题标签 [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 - 在引擎盖下透明地使用 Grizzly?
有没有办法将灰熊动态/透明绑定到我的 Java 应用程序(可能使用 spring)?还是 Web 容器(例如 Glassfish)的 IO 处理部分?
java - SocketChannel.write() 的 Java NIO 线程问题
有时,当通过 SocketChannel.write() 发送大量数据时,底层 TCP 缓冲区被填满,我必须不断重试 write(),直到数据全部发送完毕。
所以,我可能有这样的事情:
问题是偶尔会出现大 ByteBuffer 和溢出的底层 TCP 缓冲区的问题,这意味着对 send() 的调用将阻塞一段意想不到的时间。在我的项目中,有数百个客户端同时连接,一个套接字连接引起的一次延迟可以让整个系统爬行,直到解决这个与一个 SocketChannel 的延迟。当延迟发生时,它可能会导致项目其他区域减速的连锁反应,并且低延迟很重要。
我需要一个解决方案,它可以透明地处理这个 TCP 缓冲区溢出问题,并且在需要多次调用 SocketChannel.write() 时不会导致一切阻塞。我已经考虑将 send() 放入一个扩展 Thread 的单独类中,以便它作为自己的线程运行并且不会阻塞调用代码。但是,我担心为我维护的每个套接字连接创建线程所需的开销,特别是当 99% 的时间 SocketChannel.write() 在第一次尝试时成功,这意味着不需要线程存在. (换句话说,只有在使用 while() 循环时才真正需要将 send() 放在单独的线程中——仅在存在缓冲区问题的情况下,可能有 1% 的时间)如果存在缓冲区问题只有 1% 的时间,我不会
我希望这是有道理的......我真的可以使用一些建议。谢谢!
java - 为什么我们在 Java 1.6 中从 FileChannel.map 获得 ClosedByInterruptException?
我们的一位客户偶尔抱怨说,我们的电话FileChannel.map
以ClosedByInterruptException
. Javadoc并未将此列为合法的可能性。有谁知道这里可能会发生什么?
java - 如何对使用 Thread.interrupt 的代码进行可重复的单元测试?
考虑一些调用的代码,比如说,
并且想要处理 ClosedByInterruptException 情况。我对如何进行现实的、可重复的单元测试感到困惑。
为了进行测试,我需要以某种方式将此线程与其他线程同步,并导致其他线程在正确的时间调用 Thread#interrupt。但是,所有等待的原语都是可中断的,并且可以清除中断。
现在我在正在测试的代码中有 Thread.currentThread().interrupt(根据单元测试的要求),但这与实际的异步中断并不完全相同,是吗?
java - Java NIO: IOException: Broken pipe 是什么意思?
对于我的一些 Java NIO 连接,当我SocketChannel.write(ByteBuffer)
接到电话时,它会抛出一个IOException
:“Broken pipe”。
是什么导致了“断管”,更重要的是,是否有可能从该状态中恢复?如果无法恢复,这似乎是一个好兆头,表明发生了不可逆转的问题,我应该简单地关闭这个套接字连接。这是一个合理的假设吗?IOException
当套接字连接首先仍然正确连接(而不是在某个时候失败的工作连接)时,是否曾经发生过这种情况?
SocketChannel.isConnected()
附带说明一下,在尝试 a 之前总是打电话是否明智SocketChannel.write()
,如果是这样,我是否还可以假设连接已“断开”并且如果两者都应该关闭并且SocketChannel.isConnected()
两者SocketChannel.isConnectionPending()
都是false
?
谢谢!
java - Java NIO:OP_ACCEPT 和 OP_READ 之间的关系?
我正在为我的项目重新编写核心 NIO 服务器网络代码,并试图弄清楚何时应该“存储”连接信息以供将来使用。例如,一旦客户端以通常的方式连接,我存储并关联该连接的客户端的 SocketChannel 对象,以便我可以随时向该客户端写入数据。通常我使用客户端的 IP 地址(包括端口)作为映射到 SocketChannel 对象的 HashMap 中的键。这样,我可以轻松地查找他们的 IP 地址并通过该 SocketChannel 向他们异步发送数据。
这可能不是最好的方法,但它有效,而且项目太大而无法更改其基本网络代码,尽管我会考虑建议。然而,我的主要问题是:
我应该在什么时候“存储” SocketChannel 以备将来使用?一旦连接被接受(通过 OP_ACCEPT),我一直在存储对 SocketChannel 的引用。我觉得这是一种有效的方法,因为我可以假设当 OP_READ 事件到来时映射条目已经存在。否则,每次 OP_READ 发生时我都需要对 HashMap 进行计算量很大的检查,很明显与 OP_ACCEPT 相比,客户端会发生更多这些情况。我猜我担心的是,可能有一些连接被接受(OP_ACCEPT)但从不发送任何数据(OP_READ)。这可能是由于防火墙问题或客户端或网络适配器出现故障。我认为这可能会导致“僵尸”连接不活跃但也永远不会收到关闭消息。
我重写我的网络代码的部分原因是,在极少数情况下,我得到一个进入奇怪状态的客户端连接。我在想我处理 OP_ACCEPT 与 OP_READ 的方式,包括我用来假设连接“有效”并且可以存储的信息,可能是错误的。
很抱歉我的问题不是更具体,我只是在寻找最好、最有效的方法来确定 SocketChannel 是否真正有效,以便我可以存储对它的引用。非常感谢您的帮助!
java - 网络连接的测试/故障排除工具?
我正在为我的项目的服务器端创建一个非阻塞 IO 系统。实际的实现并不重要(如果你在乎的话,它是 Java NIO),但我对在编程套接字通信时必须密切注意的细微问题感到非常害怕。我在很多领域都缺乏知识,所以我什至无法想象事情可能“出错”的所有方式......“半关闭”连接,发送比我预期更多的数据的连接等。
我正在寻找的是某种客户端工具,通过自动化连接和测试特定行为的过程来帮助测试我的系统的稳健性。某种具有不同选项的工具,用于模拟打开、使用和关闭连接的不同方式。也许它会让我一次发送一兆字节的乱码,或者尝试做一些“没有意义”的事情,所有这些都是为了我能够测试可能导致我的代码中断的随机、罕见的事情,或者无法识别“断开”的连接并关闭它。
是否存在某种工具?另一种方法可能是一些 Java 代码/单元测试。有什么想法吗?非常感谢!
java - Java:每个连接线程阻塞 IO 与 NIO 的完整代码示例?
好吧,我要疯了。我一直在为我的服务器重写 NIO 代码,并且遇到了一些真正令人头疼的问题。底线是让 NIO “正确”是非常困难的。有人向我指出http://rox-xmlrpc.sourceforge.net/niotut/上的 Rox 教程,这似乎走上了一条不错的道路,但并不像我想要的那样完整。例如,我需要知道如何在发送了排队的传出 ByteBuffers 之后才关闭服务器端的连接。SocketChannel.close() 很突然,如果过早完成可能会丢失数据。我还需要发送大于读取的 ByteBuffer 的大数据包。Rox 代码(也不是我看过的任何其他代码)处理这个问题。还有很多地方似乎未正确处理未捕获的异常。在我的测试中存在一些错误,鉴于 NIO 的复杂性,目前尚不清楚如何正确处理它们。
无论如何,当我试图解决这些问题时,会出现更多棘手的细节,而且变得相当复杂。所以我正在考虑一种完全不同的方法。很多人都在说 NIO 非常容易出错,而且不必要地令人困惑和复杂。他们提倡使用“每个连接线程”模型,该模型使用阻塞 IO,其中每个套接字连接都在其自己的线程上运行。这似乎是一个好主意,并且可以通过为所有连接(如在 NIO 中)设置一个选择器线程来减少前端的瓶颈,但代价是更高的开销(对于线程)。这种观点在http://paultyma.blogspot.com/2008/03/writing-java-multithreaded-servers.html和http://mailinator.blogspot.com/2008/02/kill-myth-等帖子中得到了回应请-nio-is-not-faster-than.html
与 NIO 相比,代码应该很简单,但我真的想看一些示例代码。我似乎找不到任何东西。问题是我不认为这种“每个连接的线程阻塞 I/O”策略有一个更好的名字,我实际上可以得到很好的谷歌结果。任何人都可以将我链接到一些教程或简单示例来解释使用这种“旧”的 I/O 方法并使用线程池对其进行扩展吗?或者有什么其他的智慧之言?非常感谢!
java - ByteBuffer.allocateDirect() 和 MappedByteBuffer.load() 之间的区别
我试图通过使用MappedByteBuffer
. 从规范中我看到,当我们使用MappedByteBuffer.load()
它时,它应该将数据加载到直接缓冲区中。我对此有几个问题。
我的代码片段::
上述代码的输出是 0 字节的 Direct Memory Usage(File.txt 为 1 GB)。但是,如果我取消注释该行..
我得到 100MB 的直接内存使用量。无法理解为什么会这样,至于为什么我没有得到任何直接的内存使用(即当该行被注释掉时)
尽管上述代码的 Direct Memory Usage 为 0 B,但我确实看到进程的常驻内存(使用 unix top )增加了 1 GB。但是如果我在盒子上执行“free -m”,我看不到内存使用量有任何增加。
在这两种情况下,我都对内存的结束位置感到有些困惑。
谢谢!
java - NIO 直接缓冲区何时以及如何被释放?
我有一个 C 库,它需要一个临时缓冲区作为暂存空间。我正在考虑将直接字节缓冲区的地址传递给它。
是否允许虚拟机在最终释放缓冲区之前重新定位缓冲区?在 JNI 框架消失后,本机库将保留指针。我的理解是无法缓存 JNI 本地对象引用,因为 VM 可能会在 GC 期间重新定位它们。这适用于缓冲区地址吗?
我知道如果我在 Java 中分配一个缓冲区然后让缓冲区对象超出范围,VM 将释放缓冲区内存。如果我使用 NewDirectByteBuffer 在本机代码中创建一个新缓冲区,那么释放后备内存是谁的责任?
如果我使用 NewDirectByteBuffer 在本机代码中创建一个新缓冲区和一个已被直接缓冲区使用的地址,会发生什么情况?内存会被双重释放吗?当最后一个引用它的缓冲区被垃圾收集时,VM 引用会计算内存块并尝试释放它吗?