Closed draveness closed 2 years ago
对我这个不太熟悉计算机底层原理的开发者来说,看的似懂非懂。不过感谢博主的这个系列,受益良多。
对我这个不太熟悉计算机底层原理的开发者来说,看的似懂非懂。不过感谢博主的这个系列,受益良多。
感谢支持,不清楚的话可以说一说
感谢博主的分享,受益匪浅。
但对于为什么每层的页表结构只能够负责 8 位虚拟地址的寻址?
还是有些不解。
这个是只要做到字节对齐(4的倍数)就可以,或是有什么其它的限制?
还有,为什么文中提到的最底层的页表是12位?
先谢谢博主了!
@draveness
对我这个不太熟悉计算机底层原理的开发者来说,看的似懂非懂。不过感谢博主的这个系列,受益良多。
感谢支持,不清楚的话可以说一说
嗯,已买书准备深入学习;半路出家,始终很难理解某些基本概念,需要系统的补课:-)
感谢博主的分享,受益匪浅。 但对于
为什么每层的页表结构只能够负责 8 位虚拟地址的寻址?
还是有些不解。 这个是只要做到字节对齐(4的倍数)就可以,或是有什么其它的限制? 还有,为什么文中提到的最底层的页表是12位?先谢谢博主了!
这个问题先放一放,看看其他人有没有想法
@draveness
对我这个不太熟悉计算机底层原理的开发者来说,看的似懂非懂。不过感谢博主的这个系列,受益良多。
感谢支持,不清楚的话可以说一说
嗯,已买书准备深入学习;半路出家,始终很难理解某些基本概念,需要系统的补课:-)
可以看看 Computer Systems: A Programmer's Perspective 很不错的书
想问您是通过什么工具画图的 很简洁 很清晰
@shangwen 想问您是通过什么工具画图的 很简洁 很清晰
你看看文章最底下
个人觉得以下这2者之间应该要明确区分开来,便于理解
个人觉得以下这2者之间应该要明确区分开来,便于理解
- 物理内存映射成虚拟内存,达到抽象和隔离的作用
- 因为 物理内存空间不足以支撑系统内所有进程的虚拟内存需求,利用页面置换来复用物理内存,部分进程的存储数据(暂时不需要使用的)被放入到磁盘空间中,这部分磁盘空间叫虚拟内存
你说的两者是指物理内存和虚拟内存么?
这两者都是虚拟内存,但专业点来讲,一般更倾向于把后者称为交换
这两者都是虚拟内存,但专业点来讲,一般更倾向于把后者称为交换
文中没有提到 Swap 说的都是 Paging 页面调度
这两者都是虚拟内存,但专业点来讲,一般更倾向于把后者称为交换
文中没有提到 Swap 说的都是 Paging 页面调度
噢 我回楼上那位
@AmazingRise 感谢博主的分享,受益匪浅。 但对于
为什么每层的页表结构只能够负责 8 位虚拟地址的寻址?
还是有些不解。 这个是只要做到字节对齐(4的倍数)就可以,或是有什么其它的限制? 还有,为什么文中提到的最底层的页表是12位?先谢谢博主了!
最后12位指的是一个内存页,12位正好是4K的页大小,表示数据在页内偏移量
至于为什么页表是8位地址寻址,这个不太清楚。前面的页表寻址是为了找后面的页表,按照4层页表结构来讲也已经能达到44位虚拟地址的寻址了
不知道为什么必须要8位诶,可能是为了完美的利用页面空间吧。对于64位的虚拟内存,如果低12位是偏移量,那么剩下52位作为页号。如果页面大小为4KB,页表项大小为4B,那么每个页面最多可以存放2的10次方个页表项也就是每级页表最多为10位。那么52位最少需要6级页表。这个假设不知道对不对欸。
@YangQQ1312045515 不知道为什么必须要8位诶,可能是为了完美的利用页面空间吧。对于64位的虚拟内存,如果低12位是偏移量,那么剩下52位作为页号。如果页面大小为4KB,页表项大小为4B,那么每个页面最多可以存放2的10次方个页表项也就是每级页表最多为10位。那么52位最少需要6级页表。这个假设不知道对不对欸。
我刚刚仔细看了那个四级页表的文档,发现我们被作者的图误导了,人家文档上四级页表分别占了 8\9\9\9位,作者的图画的全是8位
@YangQQ1312045515 不知道为什么必须要8位诶,可能是为了完美的利用页面空间吧。对于64位的虚拟内存,如果低12位是偏移量,那么剩下52位作为页号。如果页面大小为4KB,页表项大小为4B,那么每个页面最多可以存放2的10次方个页表项也就是每级页表最多为10位。那么52位最少需要6级页表。这个假设不知道对不对欸。
我刚刚仔细看了那个四级页表的文档,发现我们被作者的图误导了,人家文档上四级页表分别占了 8\9\9\9位,作者的图画的全是8位
可以的,确实画错了,不过 4 级页表结构中每一级都是 9 位
UPDATES: 已经修复了相关的内容
大佬想请教下,go中迭代数组是快速的因为内存地址是连续的 这里的连续是虚拟内存地址吧,物理内存不一定也连续,这样也快吗?go自己的内存管理器申请的内存是连续的所以go得数组的地址在物理内存也是连续的,能不能这么理解
在 centos7.6 中使用 top 命令,看一个 java 程序、显示两列 (VIRT )和 (RES)
VIRT RES 9.6g 1.8g
想请教一下,VIRT 多出来的部分是存放到哪里的
@lslz627 在 centos7.6 中使用 top 命令,看一个 java 程序、显示两列 (VIRT )和 (RES)
VIRT RES 9.6g 1.8g
想请教一下,VIRT 多出来的部分是存放到哪里的
针对我这个问题,我写了一个 c 语言程序,验证我的想法,虚拟内存是程序想申请的,但是可能没使用,操作系统实际没分配,这里的 VIRT 只是一个虚拟的概念,不一定存在存放到哪里的问题
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
char* mem = (char*)malloc(1 * 1024 * 1024 * 1024);
mem[1024 * 1024] = '1'; // 对于申请的 1G 空间,程序实际只使用了在 1M 偏移量的空间的 4KB 内存
sleep(1000);
free(mem);
return 0;
}
gcc main.c
以下是 top 命令执行的结果
// 可以看到虚拟内存和我申请的差不多,1G
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22405 root 20 0 1052788 348 272 S 0.0 0.0 0:00.00 a.out
以下是通过 cat /proc/pid/smaps
查看内存使用情况
7fb58f16f000-7fb5cf170000 rw-p 00000000 00:00 0
Size: 1048580 kB (c 语言程序申请的内存,虚拟内存,程序自身能看到这么多)
Rss: 8 kB (操作系统为 c 程序实际分配的内存)
Pss: 8 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 8 kB
Referenced: 8 kB
Anonymous: 8 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac sd
@knight0zh 大佬想请教下,go中迭代数组是快速的因为内存地址是连续的 这里的连续是虚拟内存地址吧,物理内存不一定也连续,这样也快吗?
切片访问元素快是因为内存连续,所以寻址比较快吧,物理内存连不连续应该不影响这个结果,访问虚拟内存的时候都需要做一次转换。
go自己的内存管理器申请的内存是连续的所以go得数组的地址在物理内存也是连续的,能不能这么理解
这个不一定
一个页占4KB即12位,剩余57-12=45=5*9,五级页表。
博主有计划写篇关于编译-链接相关的文章吗
感谢大佬的分享。
(文章开头虚拟内存的作用 "虚拟内存可以利用磁盘起到缓存的作用,提高进程访问磁盘的速度" 似乎笔误了?应该是利用主存吧)
2020-09-14 UPDATES: 已修复
博主有计划写篇关于编译-链接相关的文章吗
暂时没有,Go 语言设计与实现里面有 Go 语言的编译过程 https://draveness.me/golang/
感谢大佬的分享。
(文章开头虚拟内存的作用 "虚拟内存可以利用磁盘起到缓存的作用,提高进程访问磁盘的速度" 似乎笔误了?应该是利用主存吧)
确实有问题,已修复
写得非常好,可读性很强。
@ehds 一个页占4KB即12位,剩余57-12=45=5*9,五级页表。
逻辑顺序应该是反过来的,应该是因为一个页有 4KB 占用 12 位,一个页表占 9 位,所以四级页表共占用 12+4*9=48 位,五级页表增加了一级 48+9=57 位。
我查了一些资料也没找到为什么每一级页表要占用 9 位,这个值可能和 CPU 硬件有关(个人猜测)
感觉地址空间那块可以顺带提一下文件的加载,比如exec加载可执行文件时只创建页表映射,在执行过程中用到某一页触发缺页才将页从硬盘加载到内存中,按需加载而不是一开始全部从硬盘拷贝到内存里,更有助于理解虚拟地址空间的效果。
那虚拟内存是如何隔离各个进程空间的呢
@laotoutou 那虚拟内存是如何隔离各个进程空间的呢
各个进程会有独立的 Page Table 映射物理内存
因为页表的大小是4KB的话,64位的虚拟地址占用8B的大小,所以一个页表中可以有4KB/8B=2^9项,这样就最少需要9位才能表示
感谢分享。
文中“虚拟内存中的虚拟页(Virtual Page,PP)”,这里应该是VP?
2021-04-19 UPDATES:已修复
@draveness
@laotoutou 那虚拟内存是如何隔离各个进程空间的呢
各个进程会有独立的 Page Table 映射物理内存
那不同进程的 Page Table 隔离时又是怎么知道哪些内存能用哪些不能呢?是会扫描一下已分配的吗?
为什么每层的页表结构只能够负责 9 位虚拟地址的寻址? 答: 在csapp中4级页表中一级页表负责512G,二级页表是1G 3级是2MB 4级是4kb(真实映射) 2^9 1G = 512G 2^9 2m = 1G 2^9 * 4kb = 2MB
最后映射一个页表4KB就是负责直接去查找PPN了
64 位的虚拟内存在操作系统中需要多少层的页表结构才能寻址? 答: 应该就是4层把 48位虚拟地址 不过我不是很清楚这个虚拟地址的生成 我用go打印的是44位 c打印的是36位
大佬 我还有一个疑问 我在csapp中好像没得到答案 就是虚拟地址一直说是隔离进程中地址冲突,就是映射的时候是如何判断不会冲突的 我知道每个进程有独立的页表,cpu生成的虚拟地址会访问页表再去组装成物理地址,但是在映射的时候如何保证不会冲突
@zzm996-zzm 大佬 我还有一个疑问 我在csapp中好像没得到答案 就是虚拟地址一直说是隔离进程中地址冲突,就是映射的时候是如何判断不会冲突的 我知道每个进程有独立的页表,cpu生成的虚拟地址会访问页表再去组装成物理地址,但是在映射的时候如何保证不会冲突
我理解是操作系统负责管理内存, 程序里只知道0, 1, 2 偏移地址, 操作系统知道该程序映射的地址, 比如说地址加个前缀 000001111 + 0, 1, 2
好几年前学的了, 如有不对望大神指正
博主好~请教个问题,文章中的 Page Replacement 与隔壁文章的 Swapping,关系是什么呢?
Page Replacement 是调度策略,Swapping 是行为?
不知道是不是我没完全理解,我怎么感觉只说了 虚拟内存带来了什么
,而不是在说为什么需要虚拟内存。 虚拟内存有他的好处,不用虚拟内存也不代表只有缺点。感觉没说到什么必要性
@TXYH1 不知道是不是我没完全理解,我怎么感觉只说了
虚拟内存带来了什么
,而不是在说为什么需要虚拟内存。 虚拟内存有他的好处,不用虚拟内存也不代表只有缺点。感觉没说到什么必要性
你说了个啥...
https://draveness.me/whys-the-design-os-virtual-memory/