0

我们在 WebLogic 11g上0.6.6的 Grails 中使用 MessagePack for Java来序列化字符串数据......2.0(10.3)

public void serialize(Object object, OutputStream outputStream) 
   throws IOException {
   byte[] bytes = MessagePack.pack(object);
   outputStream.write(bytes);
   outputStream.flush();
}

我们在 WebLogic 中看到的问题是大量 STUCK 线程,因此我们转储线程堆栈并发现一些线程卡在org.msgpack.template.TemplateRegistry.lookup(TemplateRegistry:198),请参阅下面的转储。我们确信我们的代码没有引入这个问题,因为在上面的示例中,很明显我们正在MessagePack.pack()以线程安全的方式使用。查看TemplateRegistry.java 的第 198 行lookup()它是同步的,但我们不确定它为什么会导致线程卡住。

        "[STUCK] ExecuteThread: 
    '1' for queue: 'weblogic.kernel.Default (self-tuning)'" id=43 idx=0xec tid=60 prio=1 alive, in native, blocked, daemon

-- Blocked trying to get lock: org/msgpack/template/TemplateRegistry@0xfffffffe8c2fb8e8[fat lock]
    at jrockit/vm/Threads.waitForUnblockSignal()V(Native Method)
    at jrockit/vm/Locks.fatLockBlockOrSpin(Locks.java:1679)[optimized]
    at jrockit/vm/Locks.lockFat(Locks.java:1780)[optimized]
    at jrockit/vm/Locks.monitorEnterSecondStageHard(Locks.java:1312)[optimized]
    at jrockit/vm/Locks.monitorEnterSecondStage(Locks.java:1259)[optimized]
    at jrockit/vm/Locks.monitorEnter(Locks.java:2466)[inlined]
    at jrockit/vm/Locks.monitorEnterForced(Locks.java:859)[optimized]
    at jrockit/vm/RNI.c2java(JJJJJ)V(Native Method)   
    at jrockit/vm/Locks.monitorEnterUnmatched(Ljava/lang/Object;)V(Native Method)
    at org/msgpack/template/TemplateRegistry.lookup(TemplateRegistry.java:198)[optimized]         
    at org/msgpack/MessagePack.write(MessagePack.java:195)[inlined]
    at org/msgpack/MessagePack.pack(MessagePack.java:639)[inlined]
4

3 回答 3

1

根据当前的MessagePack JavaDoc,不推荐使用静态 pack(Object v) 方法,建议使用非静态方法 write(Object)。

使用示例:

MessagePack msgpack = new MessagePack();
byte[] bytes = msgpack.write(object);

你能检查一下 write 方法的使用是否解决了问题吗?

于 2012-08-31T08:49:41.573 回答
1

正如这篇博客所说,你应该使用 packer 和 unpacker 。

MessagePack msgpack = new MessagePack(); // singleton
Packer packer = msgpack.createPacker(outputStream); // createPacker every time
packer.write(object);

由于 new MessagePack() 每次都会加载类,因此如果您执行太多操作,以下代码可能会产生perm gen 内存错误。

MessagePack msgpack = new MessagePack();
byte[] bytes = msgpack.write(object);
于 2014-02-06T10:04:09.783 回答
0

我认为手动创建打包程序没有意义,只要 MessagePack.write() 为您执行此操作

public byte[] write(T v) throws IOException { BufferPacker pk = createBufferPacker();

我确实有你在谈论的 perm gen 错误,所以我正在考虑的是在我的所有应用程序中只使用一个 MessagePack 实例,你觉得这有意义吗?

于 2015-03-13T16:59:23.463 回答