鍍金池/ 問(wèn)答/Java  C  C++  網(wǎng)絡(luò)安全/ Java 和 C/C++ 的一個(gè)內(nèi)存分配的問(wèn)題

Java 和 C/C++ 的一個(gè)內(nèi)存分配的問(wèn)題

  1. 假設(shè)一臺(tái)運(yùn)行著Linux系統(tǒng)的計(jì)算機(jī)有1GB內(nèi)存,
  2. 在C/C++中用 malloc 申請(qǐng)4GB會(huì)不會(huì)成功?為什么?
  3. 在Java成員變量中也定義一個(gè)4GB的數(shù)組。請(qǐng)問(wèn)會(huì)拋出異常嗎,為什么?
回答
編輯回答
枕頭人

c

#include<stdlib.h>
#include<string.h>

int main(void){
    long mem = 1000L*1000*1000*64;//64G, 我的機(jī)器有16G內(nèi)存
  
    char* f = malloc(mem);

    memset(f,0xff, mem-1); //注釋掉這一行你會(huì)成功的

    free(f);

}
gcc melloctest.c
./a.out

運(yùn)行時(shí)你會(huì)看到段錯(cuò)誤 (核心已轉(zhuǎn)儲(chǔ))(我就不提Segmentfault,呵呵!)

java

public class Test{
    static final int mem = 1000*1000*64;//64M //java 不能用long聲明數(shù)組
    public static void main(String[] args){       
        int a[][] = new int[1000][];
        
        for(int i=0;i<1000; i++)
           a[i] = new int[mem];

        a[999][mem-1]=10086;
        System.out.println(a[999][mem-1]);
    }

}

運(yùn)行時(shí)你會(huì)看到

java Test
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at Test.main(Test.java:10)
    

## 結(jié)論

c: 聲明沒(méi)問(wèn)題,分配沒(méi)問(wèn)題, 使用了就不行
java: 聲明沒(méi)問(wèn)題,分配都不行,更別說(shuō)使用了

2018年3月24日 19:07
編輯回答
我不懂

代碼宇宙 所說(shuō),這取決于多個(gè)因素。

理論上單進(jìn)程可以尋址的空間大小取決于硬件設(shè)備。

  • 以我們常見(jiàn)的 CPU(intel 或 AMD)架構(gòu)來(lái)說(shuō),32 位可以尋址 2^32 (4GB),而 64位可以尋址 2^64 (16EB)。

但實(shí)際上單進(jìn)程可使用的內(nèi)存空間低于理論值,它還取決于操作系統(tǒng),及應(yīng)用程序。

  • 現(xiàn)代操作系統(tǒng)多使用 虛擬內(nèi)存地址 概念,它為每一個(gè)進(jìn)程分配同等大小的地址空間,而實(shí)際內(nèi)容(透過(guò)地址轉(zhuǎn)換)可能存在物理內(nèi)存中,也可能轉(zhuǎn)存到其他介質(zhì),如 windows 的虛擬內(nèi)存文件,linux 的 swap 分區(qū)。當(dāng)物理內(nèi)存和轉(zhuǎn)存介質(zhì)不夠用時(shí),可能導(dǎo)致已經(jīng)申請(qǐng)的內(nèi)存用不了。
  • 雖然每個(gè)進(jìn)程都擁有獨(dú)立完整的內(nèi)存空間,但不是所有的空間都可以使用,操作系統(tǒng)通常預(yù)留部分空間,用以裝載運(yùn)行進(jìn)程的必要組件。

總結(jié)

在C/C++中用 malloc 申請(qǐng)4GB會(huì)不會(huì)成功?為什么?
在Java成員變量中也定義一個(gè)4GB的數(shù)組。請(qǐng)問(wèn)會(huì)拋出異常嗎,為什么?
  1. c/c++32位系統(tǒng)中失敗,而 64位系統(tǒng)成功。
  2. java 參照上一條,還取決與 jvm 的最大內(nèi)存限制,請(qǐng)查閱 java-Xmx 啟動(dòng)參數(shù)。
2018年6月29日 18:13
編輯回答
法克魷

如果環(huán)境是64位的,應(yīng)該都沒(méi)有問(wèn)題,物理內(nèi)存不夠可以使用虛擬內(nèi)存的(需要確認(rèn)系統(tǒng)配置的虛擬內(nèi)存是否足夠大)。

對(duì)于java,還需要注意兩點(diǎn),一是jre版本也必須是64位的,二是啟動(dòng)時(shí)需要用參數(shù)指定最大內(nèi)存大小,因?yàn)槟J(rèn)的值比較小。

如果系統(tǒng)是32位的,因?yàn)槟軌蚴褂玫淖畲髢?nèi)存只有4GB,而其中必須分一部分給操作系統(tǒng)使用,所以應(yīng)用程序能夠使用的內(nèi)存通常只有1~3GB,因此是無(wú)法使用到4GB的空間的。

2018年2月16日 21:23