固定对象溢出异常?

emi*_*lly 15 java exception

但是在日志中低于错误.我没有看到它对我的应用程序有任何明显影响,如UI或性能.使用weblogic Jrockit JVM.

Caused by: java.lang.InternalError: pinned object overflow!
    at java.util.zip.Inflater.inflateBytes(Inflater.java:381) ~[na:1.6.0_31]
    at java.util.zip.Inflater.inflate(Inflater.java:231) ~[na:1.6.0_31]
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:135) ~[na:1.6.0_31]
    at java.io.FilterInputStream.read(FilterInputStream.java:116) ~[na:1.6.0_31]
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264) ~[na:1.6.0_31]
Run Code Online (Sandbox Code Playgroud)

在网上,我没有找到任何特殊的pinned object overflow例外.对我来说,这看起来不像编程问题,而是与weblogic或jrockit相关的问题?

任何指针我怎么能摆脱这个?

Cra*_*Kid 4

固定对象?:

\n\n

首先让我们了解固定对象。基本上,固定我们临时标记堆上的对象,以便垃圾收集器在我们删除标记之前不会尝试移动该对象。通常,如果对象正在升级(即从年轻空间移动到旧空间)或作为压缩(碎片整理)的一部分,则该对象可能会从一个地址移动到另一个地址。但如果一个对象被固定,GC 不会尝试移动它,直到它被取消固定。

\n\n

那么我们为什么要固定一个对象呢?

\n\n

固定对于性能优化来说非常重要。在 I/O 操作期间固定缓冲区(字节数组)允许我们将其地址直接传递给操作系统。因为缓冲区是固定的,所以我们不需要担心垃圾收集器会在 I/O 操作完成之前尝试将其移动到不同的地址。

\n\n

如果我们无法固定缓冲区,则需要分配额外的本机(堆外)内存以传递给操作系统的本机 I/O 调用,并在堆内和堆外缓冲区之间复制数据。

\n\n

因此,通过将缓冲区固定到堆上的常量地址,我们可以避免执行冗余的本机内存分配和复制。

\n\n

固定对象何时可能发生溢出?

\n\n

这种情况可能发生在 JNI 调用或 I/O 调用中的错误异常处理期间。要找出真实情况,我们必须分析线程转储以找出有多少线程被阻塞,即。卡住了。

\n\n

故障排除:

\n\n

那么,当您的线程似乎卡在对 readBytesPinned 或 writeBytesPinned 的调用中时,您应该做什么?这完全取决于应用程序尝试从何处读取数据或将数据写入何处。

\n\n

让我们看一个线程卡在阻塞读取的真实示例:

\n\n
   "ExecuteThread: \'2\' for queue: \'weblogic.kernel.Default\'" id=20 idx=0x2e tid=16946 prio=5 alive, in native, daemon\n        at jrockit/net/SocketNativeIO.readBytesPinned(I[BIII)I(Native Method)\n        at jrockit/net/SocketNativeIO.socketRead(Ljava/io/FileDescriptor;[BIII)I(Unknown Source)[inlined]\n        at java/net/SocketInputStream.socketRead0(Ljava/io/FileDescriptor;[BIII)I(Unknown Source)[inlined]\n        at java/net/SocketInputStream.read([BII)I(SocketInputStream.java:113)[optimized]\n        at oracle/net/ns/Packet.receive()V(Unknown Source)[inlined]\n        at oracle/net/ns/DataPacket.receive()V(Unknown Source)[optimized]\n        at oracle/net/ns/NetInputStream.getNextPacket()V(Unknown Source)[optimized]\n        at oracle/net/ns/NetInputStream.read([BII)I(Unknown Source)[inlined]\n        at oracle/net/ns/NetInputStream.read([B)I(Unknown Source)[inlined]\n        at oracle/net/ns/NetInputStream.read()I(Unknown Source)[optimized]\n        at oracle/jdbc/driver/T4CMAREngine.unmarshalUB1()S(T4CMAREngine.java:1099)[optimized]\n<rest of stack omited> \n
Run Code Online (Sandbox Code Playgroud)\n\n

在上面的情况下,您可以从堆栈跟踪中看出 JDBC(数据库)驱动程序正在从网络套接字执行阻塞读取。因此,典型的下一步是查看是否有原因导致预期数据可能被延迟(甚至根本不会到达)。例如,我们正在交谈的数据库服务器可能挂起,可能存在延迟(甚至丢弃)数据库\xe2\x80\x99s响应的网络问题,或者可能存在某种协议不匹配,双方相信轮到对方\xe2\x80\x99说话了。分析双方的日志文件可能会提供有关所发生情况的线索。\n如果问题可重现,请收集网络跟踪并使用WireShark等工具进行分析等工具进行分析也可能很有用。

\n\n

解决方案:

\n\n

找到正确的原因后,您可以编写正确的异常处理,当然,当我们完成它时关闭 FileInputStream 以避免不必要的溢出。

\n\n

参考文献:thread_stuck_at_readbytespinned_writebytespinned

\n