我目前仍然坚持这一点,我使用的是engine.io java客户端,我必须从服务器获取二进制数据,实际上每隔16ms就会有40000字节作为字节数组。
它运行良好,我可以毫无问题地获取数据,但是,当通过这些方法解析数据时,每次接收数据时都会创建一个新的字节数组,每16ms。
观察监视器,我可以看到每次调用新字节来存储数据时,Dalvik运行时分配相同数量的内存,因此垃圾收集器会被激活很多时间并在某些时候冻结应用
16ms是否太快,垃圾收集器无法清除所有未使用的字节数组? 在android中使用字节数组时是否有推荐的大小?
编辑: 这是代码
在我的主要活动上,当来自websocket的消息到达时,我有一个这样的处理程序:
@Override
public void onMessage(ByteBuffer buffer) {
System.out.println("received message: " + buffer);
if (buffer.hasArray()) {
byte[] array = buffer.array();
}
}
之前,它由以下代码解析:
public static class InputStreamImpl extends DataInputStream {
public InputStreamImpl(InputStream in) {
super(in);
}
public byte[] readBytes(int length) throws IOException {
byte[] buffer = new byte[length];
readFully(buffer);
return buffer;
}
}
Length是来自服务器的当前字节数组的大小。 在Monitor中,我可以看到新字节[length]行增加了堆内存。
我应该放一个非常大的固定数组缓冲区并重用相同的缓冲区吗?
谢谢!
答案 0 :(得分:2)
一般来说,垃圾收集器会在积累了足够的垃圾时运行。它消耗的时间大致取决于堆上有多少总对象。 byte[40000]
是一个中型对象,但每秒60个加起来为2.4 MB / s,或接近150 MB / min。对于小型设备而言,这是非常重要的,例如您期望找到运行Android(对于您的数据计划而言,如果您实际上正在以该速率接收数据,那么这一点非常重要。)
作为一般原则,您应该根据您需要或实际预期每个I / O事务接收的数据量适当调整缓冲区大小。完成后,您希望重用该缓冲区并避免不必要地复制它。这些都是可能的。你没有提供任何代码,所以我无法开始猜测你的缓冲区被复制的原因。