栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JVM - 直接内存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JVM - 直接内存

# JVM - 直接内存

JDK版本:1.8

# 1、直接内存(Direct Memory)

​ 直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。但是这部分内存也会被频繁地使用,而且也会导致OutOfMemeory异常。

​ 在JDK 1.4版本中引入了NIO类,引入了一种基于通道(Channel)于缓冲区(Buffer)的I/O方式,它可以直接调用Native函数分配堆外内存空间,然后通过存储在堆中的DirectByteBuffer对象作为这块空间的引用以此来对其进行操作。这样就避开了JVM于操作系统之间的内存屏障,减少了在Java堆与Native堆中进行来回复制的额外开销,在某些场景中可以显著提高性能。同时访问直接内存的速度也会优于Java堆,即读写性能高。

​ 本机直接内存的分配是不会受到JVM堆内存大小的限制,但是它还是会受到本机总内存(包括物理内存,SWAP分区或者分页文件)的大小以及处理器寻址空间的限制。一般在配置虚拟机参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理和操作系统级的限制),从而导致动态进行扩展时出现OutOfMemory异常。

​ 也正是因为直接内存不是虚拟机运行时数据区的一部分,直接内存不受JVM内存回收管理,所以其分配回收成本也较高。直接内存大小可通过MaxDirectMemorySize选项进行配置,如果不进行指定默认与堆空间的-Xmx参数值保持一致。

# 2、直接内存与非直接内存差异

使用非直接内存进行IO读写文件时,需要与物理磁盘进行交互。在执行读写操作时,JVM与OS直接存在内存屏障,所以进行数据的交互时就会进行来回复制。换而言之就是需要由用户态切换到内核态,内核态中需要同时维护两份重复数据,这样带来的额外性能开销是非常大的。

如下为非直接内存JVM与OS之间的数据交互图:

使用直接内存进行IO读写文件时,直接调用Native函数分配堆外内存空间,并且这部分内存可以通过存储在堆中的DirectByteBuffer对象对其进行操作,避免了内存屏障同时也只需要维护一份数据。避免了不必要的性能开销。

如下为直接内存JVM与OS之间的数据交互图:


GitHub源码地址:https://github.com/kapbc/Java-Kapcb/tree/master/src/main/java/com/kapcb/ccc/jvm

备注:此文为笔者学习JVM的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。

更多Java技术笔记可扫码关注下方微信公众号。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/719193.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号