我8G DDR4 2400內存, Windows10系統


這個問題我想應該是仁者見仁智者見智的,所以沒有必要diss別人的回答,大部分人都可以在自己的經驗範圍內給出一個合理的參考做法,這是沒有問題的,而且應該沒有人會說自己是標準答案,因為這本身就沒有標準答案。所以我下面不會說「應該設置為XXX」這種話,如果你單純對此有所期待,那麼可以不用費時間向下閱讀。

既然這個問題推到我這了,我也湊個熱鬧稍微說一個個人看法。首先我不是Windows用戶,但是虛擬內存不是隻有Windows用戶才會面臨的概念。因為虛擬內存本身是一個操作系統層面的通用概念。在說如何設置虛擬內存之前,我先簡單說一下什麼是虛擬內存。

先來看一個例子,有這樣一個程序:

// mytest.c
#include &
#include &
#include &

int main(int argc, char *argv[])
{
size_t n = 0;

n = atoi(argv[1]);
if (!malloc(n*1024*1024*1024)) {
perror("malloc");
return 1;
}

while(1);

return 0;
}

我們用這個程序來申請內存分配,先來看一下我當前機器的內存情況:

$ free -h
total used free shared buff/cache available
Mem: 15Gi 2.2Gi 9.6Gi 350Mi 3.3Gi 12Gi
Swap: 7.6Gi 0B 7.6Gi

可以看到物理內存有15G左右,當前有12G available,交換空間或者說這個題目所指的「虛擬內存」有7.6G。那麼大家覺得我申請分配多少,或導致no memory的錯誤呢?

首先一次性申請不超過物理內存應該是沒有問題的,那一次性申請超過物理內存,但是小於物理內存加「虛擬內存」的總大小呢?

$ ./mytest 18

沒有問題,返回成功。那我們一次性申請超過物理內存加「虛擬內存」的總和呢?

$ ./mytest 50
malloc: Cannot allocate memory

這就不行了,系統直接返回錯誤,告訴你不能分配那麼多內存。那我們每次申請5GiB,連續申請十次呢?

$ for i in `seq 1 10`;do ./mytest 5 done

都沒有問題,全部成功。為什麼一次性申請50G不行,分批就可以呢?因為一次性申請50G,系統直接就能判定沒有這麼多。但是如果你分開使用,雖然我們每次都申請5G,但系統並沒有真的給我們5G,只有在真的需要寫入的時候,才會真的讓這5G對應物理地址。我們現在可以看到,即使我們做了5G * 10的malloc操作,內存的狀態仍然是沒有變化:

$ free -h
total used free shared buff/cache available
Mem: 15Gi 2.2Gi 9.6Gi 350Mi 3.3Gi 12Gi
Swap: 7.6Gi 0B 7.6Gi

說明這5G * 10的內存根本沒有實際分配。為了讓內存得到實際分配,我們對malloc出來的內存進行寫入操作,將程序改為:

...
p = malloc(n*1024*1024*1024);
if (!p) {
perror("malloc");
return 1;
}
memset(p, 0xff, n*1024*1024*1024);
...

這回我們先試試分配並寫5GB:

$ ./mytest 5
$ free -h
$ free -h
total used free shared buff/cache available
Mem: 15Gi 7.2Gi 4.6Gi 357Mi 3.3Gi 7.2Gi
Swap: 7.6Gi 0B 7.6Gi

可以看到物理內存的used從2.2變成7.2G。如果我們要分配並寫超過物理內存大小,但是小於物理內存加上「虛擬內存」大小呢?

$ ./mytest 17
$ free -h
total used free shared buff/cache available
Mem: 15Gi 14Gi 234Mi 83Mi 255Mi 155Mi
Swap: 7.6Gi 4.8Gi 2.8Gi

我們可以看到這麼做也是可以的,而且物理內存已經基本全部佔用,「虛擬內存」也佔用了很大一部分。這時候我寫這個回答也變得有一點點卡頓了,因為我的內存已經所剩無多了。但還可以接受,而且漸漸緩解,因為我當前寫回答的進程是主要活躍進程,mytest那個測試進程佔用的內存應該被部分換出到硬碟上的虛擬內存去了,給我當前的瀏覽器進程預留了足夠的物理內存。

在虛擬內存已經所剩無多的狀態下,我們嘗試超額申請內存試試,我們一共加起來也就剩3G左右了,我們申請並寫入5G試試。注意此時是有風險的,不同的系統可能會有不同的應對方式。在實際這麼做之前,我預計我的系統(kernel-5.3.11-100.fc29.x86_64)應該會觸發OOM killer,殺死系統認為大量浪費佔用內存的進程,以維持系統正常運行(當然不排除誤殺我當前的瀏覽器進程……但我認為概率不大,畢竟上面有一個佔了17G的無用進程頂在我前面呢:)。讓我們試試看(我先保存個草稿;):

$ ./mytest 5

在經過了一小段時間的卡頓後,這個程序執行成功了,我的瀏覽器沒有被殺死,系統也沒有崩潰。而且在預料之內的,那個佔用17G內存的程序被內核主動殺死了:

./mytest 17
Killed
$ dmesg
...
[17122.987802] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/session-2.scope,task=mytest,pid=25832,uid=1000
[17122.987809] Out of memory: Killed process 25832 (mytest) total-vm:17828096kB, anon-rss:11570352kB, file-rss:0kB, shmem-rss:0kB
[17123.578327] oom_reaper: reaped process 25832 (mytest), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

通過上述例子,我們可以對物理內存和「虛擬內存」有一個大概的印象。下面我們就來簡單說一下什麼是虛擬內存。

首先對於計算機技術來說,「虛擬內存」這個概念首先是指一種內存管理的技術方式,而不是指某一個「東西」。虛擬內存顧名思義,就是「虛構的」內存地址空間。這種虛構基於一種映射,進程在運行時面向的地址空間實際上是一層邏輯抽象的連續地址,每一個地址下面可能對應散落的物理內存,可能對應硬碟空間等,當然也可能什麼都不對應,下面暫時是空的。在實際進行分配讀寫時,給需要實際物理內存的虛擬地址分配實際物理內存,暫時不需要實際物理內存的可以暫不分配,物理內存不夠時也可以將已經分配的但是暫時不用的內存頁寫回硬碟,釋放其所佔用的實際物理內存。這樣就保證程序在使用「虛擬」內存地址時不必過於擔心實際的物理內存不夠的情況。舉個不是特別對等的例子,就好像是一個人用三塊磚頭墊在腳底下走過一片泥濘的道路一樣,對於這個人來說他面向的就是一整片連續的道路(虛擬內存),雖然實際磚塊(物理內存)很少,但是他可以通過不斷把走過的地方的磚往前移動到沒走過的地方,來達到一種近似「腳下總有路可以走」的效果。這實際上是虛擬內存的主要目的之一,讓進程總覺得自己「有路可走」。甭管裏子多忙多疲於奔命,面子上總要先過得去, 這就是好面子的虛擬內存 :)

然後我們在說一下這個問題中,以及日常經常被人提到的「虛擬內存」。上面我們說了,在虛擬內存技術中,硬碟等外部存儲介質可以充當虛擬內存地址的臨時媒介。所以開始有人將這部分外部存儲空間稱為虛構的內存,也簡稱為虛擬內存。所以這裡的虛擬內存不是指一種技術,而是指一個東西。當然也有的人將整個內存地址空間都叫「虛擬內存」,因為他們認為使用的本來就是虛擬內存地址,不是實際物理地址。所以「虛擬內存」這個詞現在變得很難單獨提出來說是指什麼,必須在較明確的上下文語境中才能「猜測」其具體代指什麼。對於這個問題的語境,它應該是指除物理內存以外,用於交換物理內存頁的,位於外存的交換空間,常見的稱呼可能包括「虛擬內存」,「交換空間」、「虛存文件」、「頁面文件」等等等等。

在早期,程序員處理內存不足的方式是使用一種近乎手動的覆蓋技術,比如在幾百K的內存空間上需要運行幾M大小的程序,程序員需要將這個幾M的程序在程序設計和編寫時就手動分割,將它們分割為可以獨立運行很多部分,然後讓它們分時運行,每部分運行時都不超過內存大小。這種技術在現在實際上也沒有完全意義上的消亡,這仍然是很多大型程序設計時應該考慮的。

不過這個和我們要說的「虛擬內存」這個東西沒太多關係,我們要說的是虛擬內存技術的第二種,自動交換技術。交換技術的目的就是為了讓正在或需要馬上運行的程序能獲得足夠的物理內存資源,讓不需要運行,或即將退出運行週期的進程讓出佔用的物理內存資源,將它們暫時保存到外存中去。這個技術就是由內存管理提供的功能,而不需要程序員手動幹預。這就有點像你和另一個人分攤房費,分時租住同一個房間似的。

隨著技術的發展,我們現在一般不需要以整個進程為粒度進行整體的換入換出,程序的運行也不需要一次性全載入進內存,運行的過程也不需要全部程序都在物理內存上。但是頻繁換入換出仍然是性能的瓶頸。為了減緩換入換出帶來的影響,增加可用物理內存和增加外存的訪問速度是兩種可選方案,而且這兩種方案不衝突,有條件的完全可以同時選擇。說簡單了就是買更多的內存,和買更快的SSD等設備。

說了這麼多,那麼我們回過頭說虛擬內存設置,也就是說我們設置多少的用於交換的外存空間更合適呢?可能有1.5~3倍左右物理內存這種說法。但是這個數字不是絕對的,也沒有特別大的參考性。一般來說使用默認值就行,個人覺得0.5~2倍都在理論可接受範圍內,你也要根據自己的實際內外存儲情況進行評估,不能簡單的說多少就合適。還是那句話,不懂就默認,除非默認的出現很大問題。如果你發現默認設置下系統卡頓嚴重,那麼你可以嘗試通過調整虛擬內存大小來嘗試找到一個合適你使用習慣的更好的「值」。這將是綜合專業分析的過程,或者是一個「瞎貓碰死耗子」的過程。有時通過調整,確實能達到一定的改善作用,但不絕對,也行你現在默認的就已經是很好的狀態了。這時候說明你需要的就是增加物理內存大小,以及換更快的外存儲器。


這個問題是沒有標準答案的。唯一相對可靠的是系統自行管理。

虛擬內存就是物理內存不夠用的時候把一些很少訪問的內存數據轉存到硬碟上,然後把這部分內存騰出來分配給其它應用。因為硬碟比內存慢的多,只要用虛擬內存就必然卡慢。所以最理想的狀態當然是不使用虛擬內存,完全只用物理內存,避免卡慢。

然鵝物理內存有多少,需要多少,很顯然每人不同。有人天天打開電腦就追兩部劇順手聊兩句QQ,4G就夠。有人開一堆虛擬機研究分散式計算的,64G都不夠。

如果日常使用程序比較固定,內存需求通常比較穩定的,直接按照需求買稍大容量的物理內存就行。但難免有些時候因為某些特殊原因對內存的需求超出了平常需要。例如寫篇文章要查大量資料打開上百個網頁標籤;臨時處理一張超高解析度的照片;平時頂多隻用一個虛擬機的但為了某個需要同時開兩個甚至三個…

按極端情況的最大需求買內存傷錢,除非礦裏有家如 @琴梨梨, 而極端情況到底需要多少內存,又有誰能說的準呢?


我物理內存32G,然後我在C盤設置了48G,在D盤設置了64G。

我情況特殊,我要用3DMAX渲染,如果只是讓系統自己管理經常圖多的時候就不夠,這麼設置後就再也沒有不夠用過。


128m,目的是避免某些睿智程序讓我把虛擬內存打開

虛擬內存速度慢,發現內存不足直接加錢買物理內存就完事了


修改:

添加關機自動清除虛擬內存頁面文件,這條更實用。

設置步驟如下:

  1. 運行:gpedit.msc進入組策略對象編輯器。
  2. 如圖依次打開如下內容:「計算機配置」---「Windows 設置」---「安全設置」---「本地策略」---「安全選項」---「關機:清除虛擬內存頁面」。
  3. 右擊「屬性」點擊「已啟用」。
  4. 確定,這樣設置就ok了。

對於沒有組策略的解決方案如下:

  1. 按系統快捷鍵win+r運行regedit打開註冊表編輯器。
  2. 查找到「HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Session Manager/Memory Management」,然後在右邊的列表中雙擊「ClearPageFileAtShutdown」。
  3. 在彈出的「編輯DWORD」值對話框中改為1。
  4. 重新啟動計算機,使修改生效。

原答案:

我曾把虛擬內存交給系統自動管理,結果系統慢慢分配了10G的虛擬內存,而本機只有8G內存。結果越用越卡。

每次系統變卡時,查看虛擬內存都是特別大,8G以上。

虛擬內存,本質就是RAM與 硬碟之前的緩存。它不是越大越好。當這個緩存過大時,維持這個緩存就是很耗資源的事情,它使page 在硬碟與RAM 中寫入寫出增多, 使RAM的命中率降低, 是喫力不討好的事情。

虛擬內存不會自動清零的,如果虛擬內存的垃圾回收故障,其內存空間越佔越大,影響系統性能。

因此,虛擬內存既不應該設置過大,也不應該交系統管理。

怎麼辦呢?按推薦值寫死就好了,減少一些自由度, less is more.


當今內存泛濫的世界,對於個人用戶這玩意真的還有存在的意義,不懂。


首先,本人小米pro/8GB,虛擬內存的大小取決於用途,如果只是日常使用,建議設為0。如果需要使用Photoshop處理較高像素圖片,或者要大型玩遊戲,建議設置得大一點,至少8GB。


虛擬內存是十年前內存奇缺狀態下的產物,那時候標配是512到1g的內存,甚至還有更低的,導致運行的程序一多就會不夠用。虛擬內存就是將硬碟的部分空間拿來當作內存使用,而硬碟的讀寫速度和內存差了幾個數量級,因此同時運行的程序一多就會非常卡。

家用電腦4G以上內存的幾乎不用設置虛擬內存,因為幾乎完全夠用了。


系統自動。


不建議關,Windows 沒有 overcommit,關了有的程序申請不到內存,就出錯退出了,設成自動就行了


推薦閱讀:
相關文章