2015-08-15 90 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 
} 

因爲從緩存中讀取不增加的位置。

相關問題