【发布时间】:2013-12-21 08:02:47
【问题描述】:
我正在开发用于文件交换的客户端-服务器架构,这是为了我自己的目的。除了内存使用,一切都很好。在我发送了一些文件后,我意识到当我尝试发送一些视频(大约 900MB)时,我的应用程序内存管理不是那么有效,我的客户端和服务器的内存使用量约为 1.5GB。
我使用了 NetBeans 的 Profiler,它说问题是字节数组。
//Client side
FileInputStream f = new FileInputStream(file);
FileChannel ch = f.getChannel();
ByteBuffer bb = ByteBuffer.allocate(8192*32);
int nRead = 0;
while ((nRead = ch.read(bb)) != -1) {
if (nRead == 0) {
continue;
}
bb.position(0);
bb.limit(nRead);
send.writeObject(Arrays.copyOfRange(bb.array(), 0, nRead));
send.flush();
bb.clear();
}
f.close();
ch.close();
bb.clear();
send.writeObject(0xBB);
send.flush();
//Server side
FileOutputStream fos = new FileOutputStream(file);
FileChannel fco = fos.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(8192 * 32);
do {
Object received = download.readObject();
if (received instanceof byte[]) {
byte[] bytes = (byte[]) received;
buffer.put(bytes);
buffer.flip();
buffer.position(0);
buffer.limit(bytes.length);
fco.write(buffer);
buffer.clear();
} else if (received instanceof Integer) {
Integer tempx = (Integer) received;
state = (byte) (tempx & (0xFF));
}
} while (received != (byte) 0xBB);
fco.close();
fos.close();
有没有办法修复它,我的意思是可以清理用过的内存吗?限制字节缓冲区不能正常工作,所以我限制了缓冲区中的字节数组,我没有附加整个代码,因为处理文件是个问题。
来自 PROFILER 的屏幕 - 客户端的内存使用情况 http://i.stack.imgur.com/ouTDk.png
【问题讨论】:
-
你为什么打电话给
send.flush?!您是在测量物理内存还是虚拟内存的使用情况? -
抱歉我完全忘记了,发送的是ObjectOutputStream,下载的是ObjectInputStream。
-
我在 Windows 任务管理器中测量物理内存。
-
你为什么要创建一个 ByteBuffer 来用字节填充它然后再写出来?不能直接写出byte[]吗?
-
还值得检查
ByteBuffer上的isDirect()方法。直接缓冲区经常有奇怪的内存管理策略,可能存在于垃圾收集堆之外。