<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    一個爭議很大的問題(文末送書)

    共 4744字,需瀏覽 10分鐘

     ·

    2022-06-20 11:48

    粉絲福利:文末送書

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

    其中,第一個問題「在 4GB 物理內(nèi)存的機器上,申請 8G 內(nèi)存會怎么樣?」存在比較大的爭議,有人說會申請失敗,有的人說可以申請成功。

    這個問題在沒有前置條件下,就說出答案就是耍流氓。因為在 32 位操作系統(tǒng)和 64 位操作系統(tǒng)場景下,答案是不同的。

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

    所以,我們要分場景討論。

    正文

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

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

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

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

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

    通過這里可以看出:

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

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

    因為 32 位操作系統(tǒng),進程最多只能申請 3 GB 大小的虛擬內(nèi)存空間,所以進程申請 8GB 內(nèi)存,在申請?zhí)摂M內(nèi)存階段就會失?。ㄎ沂稚蠜]有 32 位操作系統(tǒng)測試,我估計失敗的原因是 OOM)。

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

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

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

    現(xiàn)在,我在機器上,申請 4 GB 內(nèi)存,注意下面代碼只是單純分配了虛擬內(nè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后,申請1gb大小得內(nèi)存,此內(nèi)存起始地址:0X%x\n", addr[i]);
        }
        getchar();
        return 0;
    }

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

    我們可以通過下面這條命令查看進程的虛擬內(nèi)存大?。?/p>


    # 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 就代表進程使用的虛擬內(nèi)存大小,RSS 代表進程使用的物理內(nèi)存大小??梢钥吹剑琕SZ 大小為 4198540,也就是 4GB 的虛擬內(nèi)存。

    然后,我們改一下代碼,在申請完虛擬內(nèi)存后,通過 memset 函數(shù)使用這個虛擬內(nèi)存,看看會發(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后,申請1gb大小得內(nèi)存,此內(nèi)存起始地址:0X%x\n", addr[i]);
            //訪問虛擬內(nèi)存
            memset(addr[i], 0, s);
        }
        getchar();
        return 0;
    }

    運行結(jié)果:

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

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

    • 在 32 位操作系統(tǒng),因為進程最大只能申請 3 GB 大小的虛擬內(nèi)存,所以直接申請 8G 內(nèi)存,會申請失敗。
    • 在 64位 位操作系統(tǒng),因為進程最大只能申請 128 TB 大小的虛擬內(nèi)存,即使物理內(nèi)存只有 4GB,申請 8G 內(nèi)存也是沒問題,因為申請的內(nèi)存是虛擬內(nèi)存,等這塊虛擬內(nèi)存被訪問了,因為物理空間不夠,就會發(fā)生 OOM。

    ??????????

    贈書福利來襲啦

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

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

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

    截止時間:2022 年 6 月 21 日 16:00  整  
     兌獎時間:2022 年 6 月 22 日 16:00截止 

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

         

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

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

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

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

    5、IntelliJ IDEA快捷鍵大全 + 動圖演示

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

    點分享

    點收藏

    點點贊

    點在看

    瀏覽 31
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報
    評論
    圖片
    表情
    推薦
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    久久综合干 | 国产高清无码在线观看视频 | 熟女人妻人妻の视频 | 美女大香蕉久久 | 色逼逼免费视频网站 |