Hessian序列化不设SerializerFactory性能问题

转于自己在公司的Blog:
[url]http://pt.alibaba-inc.com/wp/experience_1089/hessian-set-serializerfactory-performance.html[/url]

服务框架全面重构后,因换了通讯协议,采用Magic头识别新旧版本,
性能测试发现,在兼容旧版本模式下,性能下降10倍,
原来一个1ms到2ms的请求,现在需要11ms到12ms,
对比新旧版本代码,发现四个不同点:
(1) UnsafeByteArrayOutputStream是不是比ByteArrayOutputStream慢很多?
(2) 通过java.nio.ByteBuffer转换到mina的ByteBuffer映射写入慢很多?
(3) 重复使用一个ByteArrayOutputStream是不是比多个ByteArrayOutputStream慢很多?
(4) 没有设置SerializerFactory会比设置了慢很多?
逐个验证,前面三个对性能几乎没有影响,修改第四个,性能立马提升。
旧版本代码:
[code]
private static final SerializerFactory _serializerFactory = new SerializerFactory();
ByteArrayOutputStream bout = new ByteArrayOutputStream();
Hessian2Output h2out = new Hessian2Output(bout);
h2out.setSerializerFactory(_serializerFactory); // 问题所在
h2out.writeObject(msg);
h2out.flush();
byte[] content = bout.toByteArray();[/code]
新版本代码:
[code]UnsafeByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(1024);
Hessian2Output h2o = new Hessian2Output(bos);
h2o.writeObject(connReq);
h2o.flush();
byte[] content = bos.toByteArray();[/code]
新代码没有调用h2o.setSerializerFactory(serializerFactory);
就因为这一句,性能下降10倍。
我们来看一下Hessian3.2.1的源代码:
[code]
public void writeObject(Object object)
throws IOException
{
if (object == null) {
writeNull();
return;
}

Serializer serializer;

serializer = findSerializerFactory().getSerializer(object.getClass());

serializer.writeObject(object, this);
}

public final SerializerFactory findSerializerFactory()
{
SerializerFactory factory = _serializerFactory;

if (factory == null)
_serializerFactory = factory = new SerializerFactory();

return factory;
}
[/code]
看代码,在writeObject()时,如果发现没有设置SerializerFactory,会自动设一个SerializerFactory,
看起来好像没有问题,我们自己设的SerializerFactory也是直接new出来的,没做什么手脚,
那为什么性能会下降这么快呢?开始还真被这行代码唬住了,看起来没啥区别,
仔细一想,才发现,Hessian2Output对象是prototype的,
每次请求,都会创建一个实例,用完即销毁,这样的话,基于下面的方式:
[code]
if (factory == null)
_serializerFactory = factory = new SerializerFactory(); // 问题所在
[/code]
每一个Hessian2Output内部都会重新new SerializerFactory();
应改为:
[code]
private static final SerializerFactory DEFAULT_SERIALIZER_FACTORY =new SerializerFactory();
if (factory == null)
_serializerFactory = factory = DEFAULT_SERIALIZER_FACTORY;
[/code]
从这里可以看出是创建SerializerFactory的开销非常大,导致性能下降严重,
这个应该算是Hessian的BUG,这种线程安全的工厂类,就不应该在设默认值时,每次都new一个。
大家用Hessian的时候请小心这个问题。
后续还发现,不设置SerializerFactory,会出现大量线程被阻塞:
(下图为VisualVM截图,红色标识的片断为Blocked状态)
[img]http://dl.iteye.com/upload/attachment/432727/51c8a74a-88ee-38d3-9644-5e56abfb0775.jpg[/img]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值