2015-08-15 96 views
1

我得到一个:阿卡 - GC开销超过限制

java.lang.OutOfMemoryError: GC overhead limit exceeded 
    at java.nio.HeapByteBuffer.asReadOnlyBuffer(HeapByteBuffer.java:117) 
    at akka.util.ByteString$ByteString1.asByteBuffer(ByteString.scala:153) 
    at akka.util.ByteString$ByteString1C.asByteBuffer(ByteString.scala:104) 

有了这个阿卡代码:

var buffer = ByteString.apply() 
    val MsgSize = 208 

    protected def onMessage(rawMsg: ByteString) = { 

    // Messages under the size are not processed in while loop. This line appends them 
    // to be processed when enough data is present. 
    buffer ++= rawMsg 

    // Process multiple messages if present. 
    while (buffer.size >= MsgSize) { 
     // Process each message, leaves remainder for later processing. 
    } 

    // To prevent the buffer from growing uncontrollably. 
    // It is possible that at some point this fails to run for a long time 
    // which could cause the out of memory exception. 
    if (buffer.isEmpty) buffer = ByteString.apply() 
    } 

它看起来像拼接可能是问题。这是正确的方法吗?

+1

缓冲区减少或在某个点被清空了吗?循环可能?据我看来,这不是保证。你可能使用更严格定义的消息类型,而不是乱搞字节? 即使有注释,我也不会看到'if(buffer.isEmpty)buffer = ByteString.apply()'的意思。此外,你说你处理多个消息,如果存在。不应该存在缓冲区中存在多条消息的情况。你可以自己处理rawMsg,当它被处理时,下一个将从邮箱中获取。 –

+0

@AleksandarStojadinovic对。缓冲区未被正确清空。 – BAR

回答

2

事实证明,我们必须做这样的事情:

while (buffer.size >= MsgSize) { 
    val (msg, rem) = buffer.splitAt(MsgSize) 

    // Process msg 

    // buffer is now what remains 
    buffer = rem 
} 

因为从缓存中读取不增加的位置。

相关问题