自作聪明的Object Stream Caching

October 26, 2008 at 9:45 pm (java)

通常来说凡是“友好”的东西都或多或少有些自作聪明。典型自作聪明的系统之一就是臭名昭著的Windows的众多“用户友好”设定,很多情况下成了系统崩溃或者被入侵的罪魁祸首。令人费解的是不仅软件会出现自作聪明的功能。连程序设计语言的开发库也会出现自作聪明的设计。

今天跟踪到一个Java程序的leak,是由于Object Stream Caching造成的。Java的串行化接口会自动缓存输入/输出的对象,而且没有上限!这样当用户向一个流输出一定数目的对象后,流会为所有传输的对象维护一个引用,而这个引用会阻止GC进行回收。

这样设计的本意是削减重复传输相同对象的开销。But really?首先,类似的cache应该由上层应用设计,才能给开发人员足够的自由。其次,该设计判断对象重复的依据是相同的引用,而不是对象自身所实现的identicalness。可以说,大多数情况下,这种机制的判断和程序所需的重复对象的判断是有出入的,并不能真正的实现缩减传输开销的目的;第三,这个Cache的大小居然是无限的!显然设计者假设要么用户不会传输太多的对象,要么假设用户拥有一个无限的内存!更要命的是这么敏感的设计,在API文档居然一点也没有提到。

虽然设计者提供了reset()接口来释放cache的对象。但是这个reset()的存在显然和caching的初衷相违背。首先他破坏了最初cache的存在的保证对象传输唯一性的目的。其次,他只对封装的socket流有效,而对文件流,则会重置当前指针,之前写入的对象会被覆盖。

结论。尽量在处理大批量的数据时候避免序列化到文件,而是采用其他的存储机制替代;对于网络I/O,要定期的调用reset()释放cache。当然,也可以使用其他的类似的实现来替代ObjectStream,如ProtocolBueffer等等。

Permalink Leave a Comment

Follow

Get every new post delivered to your Inbox.