为什么 Java 堆可以处于物理上不连续的内存空间?

2020-11-07 11:47:11 +08:00
 zhao1014

JVM 为大对象分配内存时需要连续的内存空间,这个内存空间指的是逻辑上连续的内存空间吧?

在物理内存中对象有可能被拆分开分配到物理不连续的空间中吗?

如果 Java 堆逻辑连续的空间物理上并不连续,那么垃圾回收的过程中,由复制算法和标记-整理算法得到的空闲内存是不是也是逻辑上连续,物理上不一定连续?

JVM 运行时数据区是不是对物理内存的一部分的封装?如果是封装,那么逻辑内存与物理内存之间是不是存在一个映射关系?维护这个映射关系的开销不会很大么?为什么不要求物理连续呢?

5618 次点击
所在节点    Java
38 条回复
hello2060
2020-11-07 11:51:23 +08:00
没研究过这么高深的问题,既然 java 里都是指针,为啥必须连续空间?你一个对象创建出来只是把成员初始化了,这时候成员还不一定指向任何有意义的东西呢,连续空间有啥用
vk42
2020-11-07 11:53:42 +08:00
物理地址一般对用户态程序是不可见的,至于虚拟地址到物理地址映射是 OS 维护的事,JVM 没必要多管闲事
zhao1014
2020-11-07 11:58:35 +08:00
@hello2060 可是 jvm 分配大对象内存要求连续空间,指针指向的是对象所占内存空间的起始地址,也就是第一个字节的地址,再通过对象的类型得知该对象所需空间具体大小然后顺序读取内存
noe132
2020-11-07 12:04:18 +08:00
应用程序没有权限直接操作物理内存的,操作的都只是虚拟内存,内存分配是 OS 的工作。至于怎么分配,怎么映射,又多大开销,《操作系统》欢迎你
zhao1014
2020-11-07 12:04:36 +08:00
@vk42 好的,谢谢你
zhao1014
2020-11-07 12:06:12 +08:00
@hello2060 好像没能理解你说的意思,说的话跟你没对上,抱歉了
zhao1014
2020-11-07 12:07:31 +08:00
@noe132 你说的虚拟内存是不是虚拟存储器,本质上是存储在磁盘上,只在需要的时候才会被读取到内存里?
djFFFFF
2020-11-07 12:11:11 +08:00
@zhao1014 虚拟内存是操作系统的知识,对物理内存的抽象和隔离。看一下操作系统的知识就知道了。
zhao1014
2020-11-07 12:12:56 +08:00
@djFFFFF 好的,谢谢!
secondwtq
2020-11-07 12:20:39 +08:00
“维护这个映射关系的开销不会很大么”
这个开销由硬件承担。可能有其他的方案,但是现在主流硬件都针对这个优化,已经形成了路径依赖
julyclyde
2020-11-07 12:22:41 +08:00
应用程序看不到物理内存的地址空间
所以讨论在物理地址空间是否连续根本就是个 NULL 问题
BrettD
2020-11-07 12:31:18 +08:00
物理内存映射是操作系统内核管的事情,JVM 只管到逻辑地址
hello2060
2020-11-07 12:31:58 +08:00
@zhao1014 虚拟内存应该只是一个虚拟的东西,他映射到实际存储数据的地方,可以在内存上也可以在磁盘里。

我前面的回答其实和你问的不是一回事。但是比如说一个飞机对象,包含 100 个乘客对象,也就是飞机对象有 100 个乘客对象的 reference, 这些 reference 可以是在连续空间里的(不管实际存储位置是不是连续的),但是具体每一个乘客对象,完全可以在不连续的位置上(这个更不可能要求实际存储位置是连续的,因为每个乘客对象都是独立的,完全可以在不同的时间地点被创建)再到飞机对象被销毁的时候,乘客对象完全可能还继续存在着,要求物理连续没有意义啊。--- 如果我说的不是你问的,你可以忽略嘿嘿
zhao1014
2020-11-07 12:37:24 +08:00
@hello2060 哈哈,感谢回答
mejee
2020-11-07 12:39:45 +08:00
这里的连续地址,指的是虚拟内存的连续,而不是物理内存的连续。可以理解为虚拟内存统一受 JVM 管理,当分配大对象时候,需要在虚拟内存地址中,找到连续的内存(因为 JVM 管理虚拟内存,所以虚拟内存也是有碎片化使用的)
misaka19000
2020-11-07 12:43:13 +08:00
学学操作系统吧。。。CPU 有一个部件叫做 MMU,用来管理物理内存页。

或者看我之前写的文章
https://www.nosuchfield.com/2018/11/23/Program-compilation-linking-loading-and-running/
中第四部“装载”中介绍的过程
Jooooooooo
2020-11-07 12:53:51 +08:00
你可以研究下操作系统虚拟内存和物理内存的映射管理.
zhao1014
2020-11-07 13:03:08 +08:00
@misaka19000 感谢,发现了一个错别字,
“但其实每个旅行图手中的地图都是不一样的,这个地图保证客人绝对不会找到一个已经被别人使用的房间”旅行图→旅行团
misaka19000
2020-11-07 13:42:05 +08:00
@zhao1014 #18 感谢,已经修改
nightwitch
2020-11-07 14:40:56 +08:00
推荐去看 csapp 的第九章:虚拟内存,关键词:页表,换页和 page fault 。

对应用程序来说内部见到的地址都是虚拟的,由虚拟地址往物理地址的映射这部分是由操作系统和硬件 mmu+tlb 单元来控制的。

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

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

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

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

© 2021 V2EX