固定对象溢出异常?

时间:2016-04-30 09:32:44

标签: 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]

在网上,我找不到任何特定于pinned object overflow例外的内容。对我而言,这看起来不像编程问题,而是与之相关的问题  weblogic还是jrockit?

任何指针如何摆脱这个?

1 个答案:

答案 0 :(得分:3)

固定对象?:

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

那么我们为什么要固定一个物体?

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

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

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

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

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

<强>疑难解答:

那么当你的线程出现在readBytesPinned或writeBytesPinned的调用中时,你应该怎么做?这完全取决于应用程序尝试从中读取数据或将数据写入的位置。

让我们看一下线程执行阻塞读取的实际例子:

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

在上面的例子中,您可以从堆栈跟踪中看出JDBC(数据库)驱动程序正在从网络套接字执行阻塞读取。因此,典型的下一步是查看是否存在预期数据可能已被延迟(或甚至从未到达)的原因。例如,我们正在谈论的数据库服务器可能被挂起,可能存在延迟(甚至丢弃)数据库响应的网络问题,或者可能存在某种协议不匹配,其中双方都认为它是另一方的转过来说话。分析双方的日志文件可以提供有关发生的事情的线索。 如果问题具有可重现性,那么收集网络跟踪并使用WireShark等工具对其进行分析也可能非常有用。

解决方案:

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

参考文献:thread_stuck_at_readbytespinned_writebytespinned