java - 在将 Sockets 与 NIO 结合使用时防止内存使用率过高

标签 java file sockets nio

我正在开发用于文件交换的客户端-服务器架构,这是为了我自己的目的。除了内存使用之外,一切都很好。发送一些文件后,我意识到当我尝试发送一些视频(大约 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();

有没有办法修复它,我的意思是可以清理使用过的内存吗?限制字节缓冲区无法正常工作,因此我限制了缓冲区中的字节数组,我没有附加整个代码,因为处理文件是问题所在。

来自探查器的屏幕 - 客户端的内存使用情况 /image/ouTDk.png

最佳答案

  • 您的缓冲区是 8192 乘以 32。如果您有内存问题,请减小它们。出于网络目的,您不需要那么大。 256k 的写法也很奇怪。
  • 不要创建毫无意义的字节数组副本。 ObjectOutputStream.writeUnshared() 将执行您需要的操作。
  • 我强烈建议摆脱序列化并仅复制字节。代码变得更加简单,数据副本也更少,尤其是在接收端。

关于java - 在将 Sockets 与 NIO 结合使用时防止内存使用率过高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20713016/

相关文章:

c++ - 由于某种原因正在更改变量

javascript - 将 node.js 服务器应用于 Web 服务器

java - 如何在android中暂停和恢复倒计时器

file - 部署war文件而不是展开目录有什么好处?

php - 尽管文件存在,但 laravel 存储存在返回 false

c - 从文本文件中读取数据值以及 C 中的行数和列数

java - 行为不一致

java - 如何使用 AsyncTask 实时检索 RAM 消耗情况

Java - 查找表、数组、开关与考虑计算时间的比较

Android 客户端未从 C 服务器套接字获取响应