为了账号安全,请及时绑定邮箱和手机立即绑定

不可忽视的内存区域-直接内存

标签:
Java

一提到JVM运行的的内存划分,相信大家都会第一反应想到堆内存和栈内存。如果再分清楚一些,就是常说的运行时数据五大部分:方法区,虚拟机栈,本地方法栈,堆,程序计数器。

本文重点聊一聊直接内存(Direct Memory),直接内存并不是运行时数据区的一部分,也不是Java虚拟机规范中定义的内在区域。它通过Unsafe类的allocateMemory()方法申请分配内存,可以通过-XX:MAxDirectMemorySize指定,如果不指定 ,默认与Java堆最大值(-Xmx)一样。

说直接内存,先提一个东西,那就是NIO,至从JDK1.4中新加入了NIO,引入了一种基于通道(Channel)和缓存区(Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内在的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据。

显然,这块直接内存的分配不会受到Java堆大小的限制,但是,既然是内存,肯定还是会受到本机总内存(包括RAM以及SWAP区或者分页文件)大小又及处理器寻址空间限制。服务器管理员在配置虚拟机参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略直接内存,使得各个内存区域总和大于总物理内存,从而导致动态扩展时出现OUtOfMemoryError异常。

部分内存在程序运行中也被频繁地使用,而且也可能导致OOM。当直接内存发生内存溢出时,Heap Dump文件中不会看见明显的异常,如果发现OOM后Dump文件很小,而程序中使用了NIO(比如使用了Netty这类框架),那就要考虑这方面的问题了。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消