JVM修炼之路【8】- 直接内存

介绍完 java的内存模型之后,我们再说一个特别的东西:

直接内存

直接内存是一种特殊的内存分配方式,它允许Java程序直接通过操作系统的本地内存分配接口来分配内存,而不受Java堆的限制。

最常见的就是I/O操作 读写文件的时候

如果没有直接内存,通常在进行文件读取或写入时,数据会先被读取到堆内存中,然后再从堆内存写入到文件中。

具体地说,在传统的IO操作中,比如使用 FileInputStream 和 FileOutputStream 进行文件读写,数据会通过Java堆内存来传递。当从文件读取数据时,数据会首先被读取到堆内存的字节数组中,然后可以对字节数组进行操作。同样,当将数据写入文件时,数据也需要先被写入到堆内存的字节数组中,然后再通过IO操作写入到文件中。

这种方式需要在Java堆内存和操作系统之间进行频繁的数据拷贝,尤其是在大量数据的读写场景下,会导致性能和效率的下降。而使用直接内存则可以避免这种拷贝过程,数据可以直接在操作系统的本地内存和文件之间进行传输,提高了IO操作的效率和性能。

现在有了直接内存这个东西 我们就可以避免大量的文件数据 占用 堆内存, 我们仅仅在堆上面创建一个 buffer对象 ,而这个对象读写数据的时候 直接通过直接内存 与 系统的文件内存 进行交互,这样根本不占用堆内存空间

这样就带来了很大的优势:

无需通过Java堆分配:
直接内存不受Java堆大小的限制,可以通过操作系统的本地内存分配接口直接分配,因此不会导致Java堆空间的不足。
减少内存拷贝:
在进行I/O操作时,通常需要将数据从Java堆拷贝到内核空间,然后再进行I/O操作。使用直接内存可以避免这一拷贝过程,提高了数据传输的效率。
避免GC的影响:
直接内存的分配和释放通常由操作系统管理,不受Java虚拟机的垃圾回收器影响,因此可以减少垃圾回收的开销,提高程序的性能。
内存映射文件:
直接内存还可以用于内存映射文件(Memory-mapped Files)操作,这种方式可以将文件直接映射到内存中,可以提高文件的读写效率。

来两个常见的案例:

java 复制代码
// 分配直接内存
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
// 从文件读取数据到直接内存
try (FileChannel channel = FileChannel.open(Paths.get("file.txt"), StandardOpenOption.READ)) {
    channel.read(buffer);
} catch (IOException e) {
    e.printStackTrace();
}
// 从直接内存读取数据
buffer.flip();
while (buffer.hasRemaining()) {
    System.out.print((char) buffer.get());
}
java 复制代码
// 创建SocketChannel
SocketChannel channel = SocketChannel.open();
// 连接远程服务器
channel.connect(new InetSocketAddress("example.com", 80));
// 分配直接内存
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
// 从网络读取数据到直接内存
channel.read(buffer);
// 从直接内存写入数据到网络
buffer.flip();
channel.write(buffer);
相关推荐
东阳马生架构3 小时前
JVM简介—3.JVM的执行子系统
jvm
程序员志哥9 小时前
JVM系列(十三) -常用调优工具介绍
jvm
后台技术汇9 小时前
JavaAgent技术应用和原理:JVM持久化监控
jvm
程序员志哥10 小时前
JVM系列(十二) -常用调优命令汇总
jvm
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭10 小时前
聊聊volatile的实现原理?
java·jvm·redis
_LiuYan_13 小时前
JVM执行引擎JIT深度剖析
java·jvm
王佑辉13 小时前
【jvm】内存泄漏的8种情况
jvm
工业甲酰苯胺13 小时前
JVM简介—1.Java内存区域
java·jvm·python
yuanbenshidiaos1 天前
c++---------数据类型
java·jvm·c++
java1234_小锋1 天前
JVM对象分配内存如何保证线程安全?
jvm