如何理解 Java 的堆内内存和堆外内存

2023-08-15 15:08:26 +08:00
 Cola98

小弟在弄监控,涉及到堆内内存和堆外内存,对 Java 并不是很了解, 看了几个文章,有的说堆内内存就是 JVM 直接分配的。但是 JVM 中又有堆内存,栈内存,PC 计数器。堆内内存是指 JVM 的堆内存嘛?还是 JVM 的内存。

堆外内存有说是直接内存(Direct memory)又有的说是 Native Memory ,有点懵逼。

1654 次点击
所在节点    程序员
11 条回复
cloudzhou
2023-08-15 15:11:00 +08:00
比如你用 jni 申请了一大块内存,那这里肯定属于对外内存
Ianchen
2023-08-15 15:22:05 +08:00
一个小区,你自己房子多大,你就只能用多大,这就是堆内,你自己的房子,你自己随便折腾,计数器、栈内存等。

超出你房子的空间,且在小区内的其他空间就是堆外内存。

一套房相当于一个 JVM ,一个小区多大,就是你系统内存多大。
Cola98
2023-08-15 15:29:49 +08:00
@cloudzhou OK ,但是我暂时不需要使用 JNI ,谢谢大佬
Cola98
2023-08-15 15:30:46 +08:00
@Ianchen 了解,哪整个 JVM 都是堆内内存
zoyua
2023-08-15 16:14:24 +08:00
@Cola98 当然不是啊,这就涉及到 JVM 的又臭又长的八股文了,建议搜索一下 JVM 内存区域,里面有虚拟机栈、程序计数器、本地方法栈,然后才是堆
cheneydog
2023-08-15 16:17:15 +08:00
除了 JNI ,还有 Direct Memory 方式申请的内存应该也是堆外的
4kingRAS
2023-08-15 16:27:25 +08:00
一个是 JVM 管理的,一个不是 JVM 管理的需要手动申请,释放,跟 C++一样
cs419
2023-08-15 16:46:57 +08:00
堆内存 的 GC 是虚拟机自动执行
Direct memory 的 GC 需要你手动执行

创建对象 系统会在堆上 划出一个区域放数据
如果有数据要暂存 只能通过对象包一下
不能直接放内存里 算是二道贩子
对写代码的人友好

Direct memory 里可以直接放数据进去
并且这个数据不清理 会内存会被一直占用
灵活更高 没有中间商 但也没售后了(gc)
如果处理不当 容易内存泄漏
Chinsung
2023-08-15 17:47:11 +08:00
严格意义上来讲,不是堆内的内存都属于堆外内存,堆的大小就是通过启动命令设置进去的,除了堆之外,JVM 使用的其他内存都是堆外内存,包括 classloader ,线程,垃圾回收,直接内存( direct memory ),一般 java 讨论的堆外内存通常指的是直接内存( direct memory ),但是你是运维的话,我感觉还是把这个概念和你说清楚比较好
voidmnwzp
2023-08-15 18:15:21 +08:00
不归 jvm 管理的内存,无法自动释放
Cola98
2023-08-15 21:35:07 +08:00
@Chinsung 多谢大佬,之前关于 JVM 的内容都是八股相关,后来查看了一下文档和相关指标介绍,对堆内内存的简单理解是 JVM 中 heap 这一块的,而直接内存则是 direct memory 。也就是其他 V 友提到关于 NIO 这一块的。感谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/965476

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX