|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
再举这样一个例子:如果你想对一个数字取绝对值,你会怎么做呢?java的做法是intc=Math.abs(-166);而ruby的做法是:c=-166.abs。呵呵,这就看出了java与ruby的区别。
这是到场新公司后接办的第一个项目,利用weblogic9.2+ejb2.0,压力测试时发明速率十分慢,呼应工夫很不睬想,反省日记发明,某些ejb互相挪用时办法挪用的工夫十分长,高达300-500毫秒。十分夸大,由于两个日记之间只是距离了一个ejb挪用。经由过程threaddump剖析后发明有相称多的线程在wait,反省线程挪用绽发明是在将参数举行序列化时,线程试图加锁可是锁被占用,因而处于守候形态。思索到threaddump的这一刹时,有多达30-50个线程都在同时试图在统一个锁上加锁,很分明这里的锁合作十分严峻。
因而激烈嫌疑是java的序列化机制招致的成绩,因为weblogic/ejb之类的太庞大不便利测试,因而独自写了一个类来摹拟这类场景:
1.有大批线程在运转,时代都有序列化的操纵
2.被序列化的对象对照年夜,有大批子对象(子对象的子对象...)
运转测试代码,成绩重现,测试用开了50个线程,threaddump并剖析threaddump信息,发明49个线程处于waiting形态,只要一个线程在干活!因而抛开weblogic/ejb独自剖析java的序列化机制,起首看threaddump的线程信息:
占据锁的线程:
"testthread21"prio=6tid=0x0ad2d3b8nid=0x224runnable[0x0b48f000..0x0b48fce4]
atjava.io.ObjectStreamClass.processQueue(UnknownSource)
atjava.io.ObjectStreamClass.lookup(UnknownSource)
atjava.io.ObjectOutputStream.writeObject0(UnknownSource)
atjava.io.ObjectOutputStream.writeObject(UnknownSource)
atjava.util.ArrayList.writeObject(UnknownSource)
atsun.reflect.GeneratedMethodAccessor1.invoke(UnknownSource)
atsun.reflect.DelegatingMethodAccessorImpl.invoke(UnknownSource)
atjava.lang.reflect.Method.invoke(UnknownSource)
atjava.io.ObjectStreamClass.invokeWriteObject(UnknownSource)
atjava.io.ObjectOutputStream.writeSerialData(UnknownSource)
atjava.io.ObjectOutputStream.writeOrdinaryObject(UnknownSource)
atjava.io.ObjectOutputStream.writeObject0(UnknownSource)
atjava.io.ObjectOutputStream.writeObject(UnknownSource)
attest.Test.test(Test.java:68)
attest.Test.run(Test.java:53)
atjava.lang.Thread.run(UnknownSource)
守候加锁的线程之一:"testthread49"prio=6tid=0x0ad9a508nid=0xa9cwaitingformonitorentry[0x0bb8f000..0x0bb8fbe4]
atjava.lang.ref.ReferenceQueue.poll(UnknownSource)
-waitingtolock<0x02fb1d40>(ajava.lang.ref.ReferenceQueue$Lock)
atjava.io.ObjectStreamClass.processQueue(UnknownSource)
atjava.io.ObjectStreamClass.lookup(UnknownSource)
atjava.io.ObjectOutputStream.writeObject0(UnknownSource)
atjava.io.ObjectOutputStream.writeObject(UnknownSource)
atjava.util.ArrayList.writeObject(UnknownSource)
atsun.reflect.GeneratedMethodAccessor1.invoke(UnknownSource)
atsun.reflect.DelegatingMethodAccessorImpl.invoke(UnknownSource)
atjava.lang.reflect.Method.invoke(UnknownSource)
atjava.io.ObjectStreamClass.invokeWriteObject(UnknownSource)
atjava.io.ObjectOutputStream.writeSerialData(UnknownSource)
atjava.io.ObjectOutputStream.writeOrdinaryObject(UnknownSource)
atjava.io.ObjectOutputStream.writeObject0(UnknownSource)
atjava.io.ObjectOutputStream.writeObject(UnknownSource)
attest.Test.test(Test.java:68)
attest.Test.run(Test.java:53)
atjava.lang.Thread.run(UnknownSource)
能够发明成绩产生在类java.io.ObjectStreamClass中的办法processQueue()办法中:staticvoidprocessQueue(ReferenceQueue<Class<?>>queue,
ConcurrentMap<?extends
WeakReference<Class<?>>,?>map)
{
Reference<?extendsClass<?>>ref;
while((ref=queue.poll())!=null){
map.remove(ref);
}
}
这里的queue.poll()有加锁,持续跟进poll()的代码:publicReference<?extendsT>poll(){
if(queueEmpty)returnnull;
synchronized(lock){
returnreallyPoll();
}
}
<p>
java主要分三块,j2se:java的基础核心语言。j2me:java的微型模块,专门针对内存小,没有持续电源等小型设备。j2ee:java的企业模块,专门针对企业数据库服务器的连接维护。 |
|