new的底层原理.

我们带着问题去探讨new之后的底层原理.

  • new之后的流程是什么
  • 内存如何被读写
  • 地址如何产生
  • 地址如何表示

我们对此代码解读。
new产生的地址

1.吐槽

不得不吐槽一下,简书的markdown真抠脚,竟然没法画流程图。

2.各种概念

2.1.什么是虚拟内存(virtual memory)

  在我看来,虚拟内存更像是对内存的管理,请看下图:


一个进程的虚拟内存分布

  每一个进程的虚拟地址都是从0开始,包含放置代码区,堆,栈,和内核映射区。在这里的地址都是连续的,会被分成很多虚拟页,每一个虚拟页为4K大小,页会映射到物理内存,物理内存的地址不会重复,当一个进程开始执行或者请求堆内存,会在物理内存寻找空余的物理页(也是一页4K大小)存放。虚拟内存保证了每个进程的地址独立,不会被其他进程的访问到。
  引进虚拟内存这个概念后,会使得访问物理内存变得慢一些了,因为会有两次寻址,先去页表找物理地址,找到物理地址后才能去物理内存上读取数据。虚拟内存这个概念,也算是不错的设计吧。每个进程的地址空间都是独立的,这使得每个进程地址都是相同的基本格式(进程虚拟地址起始为0,堆,栈也是固定的起始地址),不需要知道真正的物理内存放在什么地方。由于我们编写的程序没有权限直接访问硬件,这其中的访问物理内存,会从用户态到内核态的转换,分配好内存后再从内核态转换为用户态。系统不信任我们这群坑货,才如此设计的,流程大概是这样,用户态请求内存分配 -> 系统中断 -> 内核态分配好内存 -> 系统中断 -> 返回用户态 :
user mode->interrupt->kernel mode -> interrupt -> user mode

2.2.什么是虚拟页(virtual page)

  虚拟内存由虚拟页构成,每个虚拟页4K大小。这一摞概念都是抽象的,在脑子里联想吧,你可以把虚拟内存联想成一把梯子,梯级之间的空间是虚拟页大小。

随手画了一把梯子 哈哈哈
2.3.什么是物理页(physical page)

  物理页也被称为页帧(page frame),4K大小,和虚拟页类似,只不过物理页是构成物理内存的,你把它想象成另一把梯子和梯级吧。物理页会产生内部内存碎片,但不会产生外部内存碎片,这与分段相反(还有一个种内存划分是分段的,产生外部内存碎片,但不产生内部内存碎片),这种分页的方式,类似内存对齐,关于内存对齐的理解,我写了另外一篇文章。总的来说,物理页构成了RAM(Random Access Memory,包含主存Main Memory等)。

2.4.什么是页表(page table)

  页表存在RAM。操作系统为每个进程提供一个页表,多个进程对应多个页表。页表的作用是干翻译这行的,虚拟内存的地址能够找到物理内存的地址,就是通过页表映射的,页表保存了物理地址。

2.5.什么是快表(TLB,Translation Lookaside Buffer)和cpu高速缓存

  毕竟页表是存在RAM,并且比较大,查表慢,有损性能,快表就是为了解决这个问题的。快表可以看作是页表的一个缓存,当CPU访问某一块物理内存后,把物理页存到CPU高速缓存,物理地址存到TLB。每次CPU提着虚拟地址来查表,先去TLB看看能不能找到对应的物理地址,如果找到了再去缓存找数据。如果在TLB找不到(称为TLB不命中,奇葩的命名),再去页表查找。快表本身也存在cpu缓存中,内存占用小访问速度快。unity的ECS运行速度快的其中一个原因,ECS把数据都放在一起了,当CPU访问其中一项数据,会把4K的一个物理页都存到CPU缓存中,下次使用邻近的数据时候,很可能已经被存到CPU缓存中了,所以访问速度快一些。因此,我们写代码时候,可以考虑把数据写在一起,或者函数之间调用挨着的。

2.6.VPO,VPN,PPO,PPN
  • VPN :虚拟页号(Virtual Page Number ),一页通常是4K,VPN表示在虚拟内存的第几页。
  • VPO :虚拟页偏移(Virtual Page Offset),虚拟内存的页内偏移,一页中的第几个字节。
  • PPN :物理页号(Physical Page Number),一页通常是4K,VPN表示在物理内存的第几页。
  • PPO :物理页偏移(Physical Page Offset),物理内存的页内偏移,一页中的第几个字节。

  当我们要访问某一块内存时候,会使用虚拟页号(VPN)去页表找到真实的物理页号(PPN),通过虚拟页偏移(VPO)找到真实的物理地址。这里的寻址,为什么会与PPN,VPO有关呢?一个物理地址,实际上是物理页号+偏移值构成的,一个物理页占4K大小(虚拟页也是4K),页内偏移是指在这物理页号之后位移多少字节。我们用二维数组来比喻吧 ,每一行有4K列,现在要找9K,它在2行1K列(相当于它在2物理页号1K页内偏移)。请看地址计算公式,其中2^s表示一页占用的内存大小(一般为4K):
address=PPN*2^s+VPO
  为什么此处使用VPO而非PPO,其实都一样的,页内偏移相等,VPO=PPO。

3.对整体流程的讲解

  铺垫完概念,下面开始讨论一下上述代码的执行流程。


new产生的地址
  • 应用程序编译成指令,编译时候,每块数据都有相对地址了。
  • 程序开始执行,代码被加载到主存中。
  • 指令被送至cpu的指令寄存器。
  • cpu从指令寄存器取出指令,执行new int(0);代码。
  • 在主存中分配好内存,并且映射到虚拟内存的堆中,物理地址和虚拟地址在页表中关联。
  • 与此同时,把p所在的物理页缓存到CPU高速缓存中,地址放进TLB。
  • int* p = new int(0);返回p的虚拟地址。
  • 读p的值。先去TLB查看是否存在p的地址,如果存在,去高速缓存查看值在不在。
  • 如果TLB不存在对应的地址,去页表找。

  有几点要说明的。

  • 当我们要访问p地址对应的内存时候,操作系统会检查地址是否在虚拟内存的当前进程中,操作系统不允许访问其他进程的私有内存。
  • 存在多级页表。
  • 页表有操作系统维护,分配内存时填写响应的页表项,释放内存清除响应的页表项,程序退出释放它的页表。
  • 有一种特殊情况,高速缓存和主存都没有找到,那么此时说明物理页在磁盘中。一般这种情况是爆内存了,主存不足以存放得下,那么把一部分不常用的内存放进磁盘。由于磁盘读写比较慢的原因,导致访问会卡顿。举个例子,当我们运行一个占用内存比较大的软件,内存占用为100%了,但是软件却不会闪退,原因是有一部分内存被移动到磁盘上了,把磁盘当成了主存的一部分,虚拟内存会映射到磁盘的扇区地址,去磁盘读写时候就显得比较慢了。本人曾经做过一个测试,在unity中不断加载资源到场景中,并且引用这些资源不给GC释放,观察内存占用情况,先是内存被占用为100%,然后发现E盘的可用大小变得越来越小。

  老实说,学这些对你的代码能力没多大帮助,仅仅只是个人想了解一下而已。

Author : SunnyDecember
Date : 2019.11.9
原文

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342