<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一個(gè)爭(zhēng)議很大的問(wèn)題(文末送書)

          共 4744字,需瀏覽 10分鐘

           ·

          2022-06-20 11:48

          粉絲福利:文末送書

          早上看到讀者在群里討論這些面試題:

          其中,第一個(gè)問(wèn)題「在 4GB 物理內(nèi)存的機(jī)器上,申請(qǐng) 8G 內(nèi)存會(huì)怎么樣?」存在比較大的爭(zhēng)議,有人說(shuō)會(huì)申請(qǐng)失敗,有的人說(shuō)可以申請(qǐng)成功。

          這個(gè)問(wèn)題在沒(méi)有前置條件下,就說(shuō)出答案就是耍流氓。因?yàn)樵?32 位操作系統(tǒng)和 64 位操作系統(tǒng)場(chǎng)景下,答案是不同的。

          另外,我們還要看申請(qǐng)完 8G 內(nèi)存后會(huì)不會(huì)被使用,會(huì)被使用是一種情況,不會(huì)被使用又是另外一種情況了。

          所以,我們要分場(chǎng)景討論。

          正文

          應(yīng)用程序通過(guò) malloc 函數(shù)申請(qǐng)內(nèi)存的時(shí)候,實(shí)際上申請(qǐng)的是虛擬內(nèi)存,此時(shí)并不會(huì)分配物理內(nèi)存。

          當(dāng)應(yīng)用程序讀寫了這塊虛擬內(nèi)存,CPU 就會(huì)去訪問(wèn)這個(gè)虛擬內(nèi)存, 這時(shí)會(huì)發(fā)現(xiàn)這個(gè)虛擬內(nèi)存沒(méi)有映射到物理內(nèi)存, CPU 就會(huì)產(chǎn)生缺頁(yè)中斷,進(jìn)程會(huì)從用戶態(tài)切換到內(nèi)核態(tài),并將缺頁(yè)中斷交給內(nèi)核的 Page Fault Handler (缺頁(yè)中斷函數(shù))處理。

          缺頁(yè)中斷處理函數(shù)會(huì)看是否有空閑的物理內(nèi)存:

          • 如果有,就直接分配物理內(nèi)存,并建立虛擬內(nèi)存與物理內(nèi)存之間的映射關(guān)系。
          • 如果沒(méi)有空閑的物理內(nèi)存,那么內(nèi)核就會(huì)開(kāi)始進(jìn)行回收內(nèi)存的工作,如果回收內(nèi)存工作結(jié)束后,空閑的物理內(nèi)存仍然無(wú)法滿足此次物理內(nèi)存的申請(qǐng),那么內(nèi)核就會(huì)放最后的大招了觸發(fā) OOM (Out of Memory)機(jī)制。

          32 位操作系統(tǒng)和 64 位操作系統(tǒng)的虛擬地址空間大小是不同的,在 Linux 操作系統(tǒng)中,虛擬地址空間的內(nèi)部又被分為內(nèi)核空間和用戶空間兩部分,如下所示:

          通過(guò)這里可以看出:

          • 32位系統(tǒng)的內(nèi)核空間占用1G,位于最高處,剩下的3G是用戶空間;
          • 64位系統(tǒng)的內(nèi)核空間和用戶空間都是128T,分別占據(jù)整個(gè)內(nèi)存空間的最高和最低處,剩下的中間部分是未定義的。

          現(xiàn)在可以回答這個(gè)問(wèn)題了:在 32 位操作系統(tǒng)、4GB 物理內(nèi)存的機(jī)器上,申請(qǐng) 8GB 內(nèi)存,會(huì)怎么樣?

          因?yàn)?32 位操作系統(tǒng),進(jìn)程最多只能申請(qǐng) 3 GB 大小的虛擬內(nèi)存空間,所以進(jìn)程申請(qǐng) 8GB 內(nèi)存,在申請(qǐng)?zhí)摂M內(nèi)存階段就會(huì)失敗(我手上沒(méi)有 32 位操作系統(tǒng)測(cè)試,我估計(jì)失敗的原因是 OOM)。

          在 64 位操作系統(tǒng)、4GB 物理內(nèi)存的機(jī)器上,申請(qǐng) 8G 內(nèi)存,會(huì)怎么樣?

          64 位操作系統(tǒng),進(jìn)程可以使用 128 TB 大小的虛擬內(nèi)存空間,所以進(jìn)程申請(qǐng) 8GB 內(nèi)存是沒(méi)問(wèn)題的,因?yàn)檫M(jìn)程申請(qǐng)內(nèi)存是申請(qǐng)?zhí)摂M內(nèi)存,只要不讀寫這個(gè)虛擬內(nèi)存,操作系統(tǒng)就不會(huì)分配物理內(nèi)存。

          我們可以簡(jiǎn)單做個(gè)測(cè)試,我的服務(wù)器是 64 位操作系統(tǒng),但是物理內(nèi)存只有 2 GB。

          現(xiàn)在,我在機(jī)器上,申請(qǐng) 4 GB 內(nèi)存,注意下面代碼只是單純分配了虛擬內(nèi)存,并沒(méi)有使用該虛擬內(nèi)存:


          #include <stdio.h>
          #include <stdlib.h>
          #include <unistd.h>
          #include <sys/types.h>
          #include <string.h>

          int main() {
              int ret;
              char* addr[4];
              printf("使用cat /proc/%d/maps查看內(nèi)存分配\n",getpid());
              size_t s = 1024 * 1024 * 1024;
              int i = 0;
              for(i = 0; i < 4; ++i) {
                  printf("alloc size = %d\n", s);
                  addr[i] = (char*) malloc(s);
                  printf("主線程調(diào)用malloc后,申請(qǐng)1gb大小得內(nèi)存,此內(nèi)存起始地址:0X%x\n", addr[i]);
              }
              getchar();
              return 0;
          }

          然后運(yùn)行這個(gè)代碼,可以看到,我的物理內(nèi)存雖然只有 2GB,但是程序正常分配了 4GB 大小的虛擬內(nèi)存

          我們可以通過(guò)下面這條命令查看進(jìn)程的虛擬內(nèi)存大小:


          # ps aux | grep alloc_4g
          USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
          root      7797  0.0  0.0 4198540  352 pts/1    S+   16:58   0:00 ./alloc_4g

          其中,VSZ 就代表進(jìn)程使用的虛擬內(nèi)存大小,RSS 代表進(jìn)程使用的物理內(nèi)存大小。可以看到,VSZ 大小為 4198540,也就是 4GB 的虛擬內(nèi)存。

          然后,我們改一下代碼,在申請(qǐng)完虛擬內(nèi)存后,通過(guò) memset 函數(shù)使用這個(gè)虛擬內(nèi)存,看看會(huì)發(fā)生什么。


          #include <stdio.h>
          #include <stdlib.h>
          #include <unistd.h>
          #include <sys/types.h>
          #include <string.h>

          int main() {
              int ret;
              char* addr[4];
              printf("使用cat /proc/%d/maps查看內(nèi)存分配\n",getpid());
              size_t s = 1024 * 1024 * 1024;
              int i = 0;
              for(i = 0; i < 4; ++i) {
                  printf("alloc size = %d\n", s);
                  addr[i] = (char*) malloc(s);
                  printf("主線程調(diào)用malloc后,申請(qǐng)1gb大小得內(nèi)存,此內(nèi)存起始地址:0X%x\n", addr[i]);
                  //訪問(wèn)虛擬內(nèi)存
                  memset(addr[i], 0, s);
              }
              getchar();
              return 0;
          }

          運(yùn)行結(jié)果:

          可以看到,在申請(qǐng)了 2GB 虛擬內(nèi)存后,然后馬上使用了這塊虛擬內(nèi)存,由于這臺(tái)機(jī)器的物理內(nèi)存只有 2 GB,所以發(fā)生了 OOM

          至此, 驗(yàn)證完成了。簡(jiǎn)單總結(jié)下:

          • 在 32 位操作系統(tǒng),因?yàn)檫M(jìn)程最大只能申請(qǐng) 3 GB 大小的虛擬內(nèi)存,所以直接申請(qǐng) 8G 內(nèi)存,會(huì)申請(qǐng)失敗。
          • 在 64位 位操作系統(tǒng),因?yàn)檫M(jìn)程最大只能申請(qǐng) 128 TB 大小的虛擬內(nèi)存,即使物理內(nèi)存只有 4GB,申請(qǐng) 8G 內(nèi)存也是沒(méi)問(wèn)題,因?yàn)樯暾?qǐng)的內(nèi)存是虛擬內(nèi)存,等這塊虛擬內(nèi)存被訪問(wèn)了,因?yàn)槲锢砜臻g不夠,就會(huì)發(fā)生 OOM。

          ??????????

          贈(zèng)書福利來(lái)襲啦

          Java 誕生 27 年來(lái),這本享譽(yù)全球的 Java 經(jīng)典著作《Core Java》一路伴隨著 Java 的成長(zhǎng),得到了百萬(wàn) Java 開(kāi)發(fā)者的青睞,幾乎出現(xiàn)在每個(gè)“學(xué)Java要看什么書”類似的書單里,影響了幾代技術(shù)人

          27年間,每當(dāng) Java 有新的 LTR 版本發(fā)布,這本書都會(huì)隨之更新,這次也不例外。現(xiàn)在,針對(duì) Java 17 新特性的《Java核心技術(shù)》第 12 版*中文版(卷1)終于上市了!

          《Java核心技術(shù)》第 12 版涵蓋了 Java 17 的最新特性,相應(yīng)調(diào)整了部分內(nèi)容結(jié)構(gòu),同時(shí)延續(xù)之前版本的優(yōu)良傳統(tǒng),利用清晰明了的示例加以解釋,并提供了全部示例代碼,以便讀者學(xué)習(xí)和靈活應(yīng)用。它將續(xù)寫從前的輝煌,使開(kāi)發(fā)者能及時(shí)跟上 Java 前進(jìn)的步伐

          截止時(shí)間:2022 年 6 月 21 日 16:00  整  
           兌獎(jiǎng)時(shí)間:2022 年 6 月 22 日 16:00截止 

          #留言有禮# 以上的書你喜歡嗎?分享一下你想要這本書的理由!或者你對(duì)本文的見(jiàn)解,活動(dòng)截止時(shí)小編選出10位幸運(yùn)小錦鯉,中獎(jiǎng)?wù)呖色@得實(shí)體書籍一本,我們包郵贈(zèng)送~

               

          1、拖動(dòng)文件就能觸發(fā)7-Zip安全漏洞,波及所有版本

          2、進(jìn)程切換的本質(zhì)是什么?

          3、一次 SQL 查詢優(yōu)化原理分析:900W+ 數(shù)據(jù),從 17s 到 300ms

          4、Redis數(shù)據(jù)結(jié)構(gòu)為什么既省內(nèi)存又高效?

          5、IntelliJ IDEA快捷鍵大全 + 動(dòng)圖演示

          6、全球第三瀏覽器,封殺中國(guó)用戶這種操作!

          點(diǎn)分享

          點(diǎn)收藏

          點(diǎn)點(diǎn)贊

          點(diǎn)在看

          瀏覽 31
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操逼视频。 | 在线免费观看视频a | 人人插人人靠 | 无码黄色电影 | 女人被操在线观看 |