MessagePack模板查找导致WebLogic中的线程卡住?

时间:2012-08-30 19:50:51

标签: multithreading grails weblogic msgpack messagepack

我们在WebLogic 11g 0.6.6上使用Grails 2.0中的Java使用MessagePack (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, line 198lookup()已同步,但我们不确定为什么会导致线程卡住。

        "[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]

3 个答案:

答案 0 :(得分:1)

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

用法示例:

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

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

答案 1 :(得分:1)

你应该使用打包器和解包器,this blog说。

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

如果你做的太多,以下代码可能会产生perm gen memory error,因为新的MessagePack()每次都会加载类。

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

答案 2 :(得分:0)

我认为手动创建打包器没有意义,因为MessagePack.write()会为你做这件事

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

我确实有你正在谈论的perm gen错误,所以我想的是在我的所有应用程序中使用一个MessagePack实例,这是否有意义你怎么想?