在每次单独调用flush the OutputStream之后ObjectOutputStream#writeObject更有效率,而不是在一系列对象写入后刷新流? (例如:写对象并刷新4次,或写4次然后只刷一次?)
ObjectOutputStream如何在内部运作?
答案 0 :(得分:2)
例如,以某种方式更好地发送四个
Object[5]
(每个都刷新)而不是Object[20]
吗?
不是更好。事实上,从性能的角度来看,它可能更糟糕。每次刷新都会强制操作系统级TCP / IP堆栈“立即”发送数据。如果您最后只进行一次刷新,则应节省系统调用和网络流量。
如果您尚未执行此操作,则在BufferedOutputStream
Socket
和OutputStream
之间插入ObjectOutputStream
会对性能产生更大的影响。这允许序列化数据在写入套接字流之前在内存中累积。这可能会节省许多系统调用,并且可以通过数量级来提高性能......具体取决于发送的实际对象。
(四个Object[5]
个对象的表示大于一个Object[20]
个对象,在第一个案例中会导致性能下降。但是,这个数据最多是边缘的,与冲洗和缓冲问题。)
此流如何在内部工作?
这是一个太明智的问题,无法合理回答。我建议您从this page上的文档开始阅读序列化。
答案 1 :(得分:1)
不,这没关系,除非你有理由相信网络链接可能会下降,部分数据是有用的。否则,它听起来就像是一种让代码变得更加复杂的方法。
答案 2 :(得分:1)
如果查看the one and only public constructor of ObjectOutputStream,您会注意到它需要基础OutputStream
进行实例化。
刷新ObjectStream的时间和方式完全取决于您使用的流的类型。 (并且在考虑所有这些时,请记住,并非所有OutputStream扩展都保证尊重您的刷新请求 - it is entirely implementation independent,因为它是在javadocs的'合同'中拼写出来的。)
但当然我们可以推理它,甚至提取代码,看看实际做了什么。
IFF底层OutputStream必须利用设备的OS服务(例如磁盘或the network interface in case of Sockets),然后flush()的行为完全取决于操作系统。例如,您可以获取套接字的输出流,然后实例化ObjectOutputStream以将序列化对象写入网络。主机操作系统的TCP / IP实现负责。
什么更有效?
好吧,如果您的对象流正在包裹ByteArrayOutputStream,那么您可能会查看一系列realloc和System.arrayCopy()调用。我可能会说,因为字节数组的实现使每个(内部)resize()操作的大小加倍,并且每次编写n(小)对象和刷新都不太可能导致n个realloc。 (假设n是一个相当小的数字)。
但是如果要包装网络流,则必须记住网络写入非常昂贵。如果您的协议允许,它会更有意义地将您的写入块(填充发送缓冲区)并刷新一次。