在 Hyper-V 管理員建立 Windows 虛擬機器,啟動要幾十秒,還會獨占數 GB 記憶體。但在同一台 PC 上,輸入 wsl 幾秒內就回到 Linux 殼層,Windows Sandbox 也在幾秒內打開一次用的桌面。1
兩者都建立在同一個 Windows Hypervisor 上(第 1 回,「你的 Windows 其實跑在哪裡?」)。第 2 回我們看到這個基礎能做出比核心更強的隔離。那麼為什麼一個重、另一個輕?
系列最終回要回答的問題只有一個。
完整虛擬機器很重──那為什麼 WSL2 與 Windows Sandbox 這麼輕?
對象讀者是把 WSL2、Windows Sandbox 與 Windows 容器用於開發與驗證,想從機制往上理解它們的輕與限制的開發者與維運人員。前提環境是 Windows 10/11;走完 Windows Sandbox 一節需要 Pro、Enterprise 或 Education 版本(Home 與 Windows Server 沒有這項功能)。背景知識是第 1 回的分割區概念。難度為中階。
1. 先講結論
輕量虛擬機器守住隔離線(專用核心與 Hypervisor 邊界),並減輕「完整客體作業系統的複本」。Sandbox 共用主機的 Windows 本身;WSL2 把客體換成小型、專用打造的 Linux;兩邊的記憶體都不是固定保留,而是與主機動態借還。
完整虛擬機器重量的來源不是隔離本身,而是重複。磁碟上另一份作業系統映像、RAM 裡另一份作業系統份量的分頁,以及每次啟動又一次完整開機。輕量虛擬機器用兩項政策切掉那份重複:「能安全共用的就共用」(Sandbox)與「不能共用就做小重建」(WSL2)。
flowchart TB
accTitle: 支撐輕量虛擬機器的三種共用
accDescr: 完整虛擬機器以往重複的作業系統映像,Sandbox 用共用、WSL2 用縮小來切掉;預設固定配置的記憶體(動態記憶體是例外)變成與主機動態借還;啟動被輕核心與最小設定取代;只有隔離邊界留下
heavy["完整虛擬機器:重複"] --> d1["磁碟:作業系統映像複本"]
heavy --> more{"記憶體或啟動?"}
more --> d2["記憶體:預設固定"]
more --> d3["啟動:完整開機"]
d1 -->|改成| s1["共用(Sandbox)"]
s1 -.-> s1b["或縮小(WSL2)"]
d2 -->|改成| s2["與主機動態出借"]
d3 -->|改成| s3["輕核心+最小設定"]
圖 1: 「同一個 Hypervisor,卻很輕」的答案骨架是:它們停掉的是重複,不是隔離。
以下依序看 WSL2、Windows Sandbox 與容器,以及各自切掉哪一種重複。
2. 完整虛擬機器在扛什麼
作為比較基準,傳統虛擬機器扛的是這些。
- 獨立的作業系統映像。它在虛擬磁碟裡持有客體作業系統的每個檔案。即使主機有同一套 Windows,也不共用。
- 粗糙的記憶體配置。傳統虛擬機器的預設是以靜態大小配置主機記憶體。Hyper-V Dynamic Memory 這類機制能在設定範圍內增減配置,但對需求變化的調整手段有限。2
- 通用的完整開機。韌體、開機載入器與整套服務,按和實體機器相同的順序啟動。
flowchart TB
accTitle: 完整虛擬機器扛的三項負載
accDescr: 完整虛擬機器扛獨立的作業系統映像、預設靜態的記憶體配置,以及通用的完整開機,那些以磁碟、RAM 與啟動時間的成本顯現
fullvm["完整虛擬機器"] --> b1["獨立的作業系統映像"]
fullvm --> more{"記憶體或開機?"}
more --> b2["預設靜態記憶體"]
more --> b3["通用開機"]
b1 -.-> c1["複本多佔磁碟"]
b2 -.-> c2["沒用到的 RAM 也佔著"]
b3 -.-> c3["要幾十秒"]
圖 2: 完整虛擬機器成本的分解,付的不是隔離,而是通用性與重複。
這些不是缺陷;它們是「客體裡可以放任何東西」這份通用性的代價。對「在 Windows Server 旁邊跑舊 Linux」這種用途,那份通用性就是價值。但對「我想現在、為了開發或驗證,跑和主機相同(或預先決定)的作業系統」這種用途,大半是多餘行李。輕量虛擬機器靠縮小用途把行李放下。
3. WSL2 ── 具備專用核心的公用虛擬機器
3.1. 結構:受管理的虛擬機器與其中的發行版
WSL2 是在輕量公用虛擬機器裡跑真正 Linux 核心的機制。3 有三點。
- 核心是真的,但是特製品。它是 Microsoft 從 Stable 分支打造的 Linux 核心,大小與效能已為 WSL2 調過。在目前標準、經 Microsoft Store 散佈的 WSL 上,核心與 WSL 套件本身一起更新,用
wsl --update套用(較舊的內建散佈則經 Windows Update)。4 因為是真正的核心,系統呼叫相容性完整,Docker 這類工具能原樣跑。 - 虛擬機器在幕後。建立、啟動、停止虛擬機器由 WSL 管理;使用者只是開啟殼層。沒有虛擬機器設定畫面,也感覺不到等待開機。4
- 發行版是虛擬機器裡的容器。Ubuntu、Debian 等發行版在一個受管理的虛擬機器裡,作為隔離容器執行。它們共用網路命名空間與核心,PID、掛載、使用者等命名空間則分開。3
flowchart TB
accTitle: WSL2 架構
accDescr: 主機 Windows 與輕量公用虛擬機器並坐在 Hypervisor 上;Microsoft 打造的 Linux 核心在虛擬機器裡執行;各發行版在其中作為隔離容器執行
hv["Hypervisor"] --> host["主機 Windows"]
hv --> uvm["輕量公用虛擬機器"]
uvm --> lk["Linux 核心(Microsoft 打造)"]
lk --> u1["Ubuntu(容器)"]
lk --> u2["Debian(容器)"]
host <-->|"互通(指令、檔案、網路)"| uvm
圖 3: 「WSL2 是虛擬機器嗎?」的答案是「是,但是受管理、幕後的虛擬機器」,即使安裝多個發行版,虛擬機器仍只有一台。
輸入 wsl 的那一刻,背面是這樣。
flowchart TB
accTitle: 從執行 wsl 指令到幾秒內回到殼層
accDescr: 執行 wsl 時若公用虛擬機器尚未執行,就啟動輕量虛擬機器與 Linux 核心;若已在執行則重用;殼層在發行版的容器裡回來
cmd["執行 wsl"] --> vmq{"公用虛擬機器已在跑?"}
vmq -->|否| bootvm["啟動輕量虛擬機器與 Linux 核心(數秒)"]
vmq -->|是| reuse["重用已在跑的虛擬機器"]
bootvm --> shell["殼層在容器裡回來"]
reuse --> shell
圖 4: 等待的只是最小的虛擬機器啟動,放下完整開機行李的效果就顯在這裡。
3.2. 檔案 I/O:放在哪一端,就是不同的事
談 WSL2 效能一定會出現的題目,是檔案放哪裡。
- 對 Linux 端檔案(ext4 虛擬磁碟) 的操作是快的。因為 Linux 核心直接和自己的檔案系統交談,解 tar 相對於 WSL1 最高約 20 倍、
git clone與npm install約 2–5 倍的加速已有報告。4 - 對 Windows 端檔案(/mnt/c 等) 的操作會變慢,因為要經過跨越作業系統邊界的檔案共用。跨作業系統檔案系統效能,是 WSL2 比 WSL1 差的一大項。4
因此規則是:「把專案檔案放在操作它們的工具所在的同一作業系統端」。4 用 Linux 建置工具處理的儲存庫放 Linux 端;在 Visual Studio 建置的方案放 Windows 端。
flowchart TB
accTitle: WSL2 檔案 I/O 路徑的分岔
accDescr: 對 Linux 端 ext4 虛擬磁碟的存取從 Linux 核心直接進行因此快;對 Windows 端檔案的存取經過跨越作業系統邊界的檔案共用因此慢
io["WSL2 裡的檔案操作"] --> place{"檔案在哪一端?"}
place -->|"Linux 端(home 等)"| ext4["對 ext4 虛擬磁碟的直接 I/O"]
place -->|"Windows 端(/mnt/c 等)"| p9["經跨越作業系統邊界的共用"]
ext4 --> fast["快(相對 WSL1 最高約 20 倍的例子)"]
p9 --> slow["容易慢"]
slow -.-> fix["修正:把檔案放在使用它的作業系統"]
圖 5: 慢的是路徑,不是 WSL2,因此改檔案放哪裡,效能問題常常就消失。
3.3. 記憶體:會增、會縮,但不一定全部還回去
WSL2 的記憶體用量(在工作管理員裡看成 vmmem 處理程序)不是固定保留;它隨使用增長與收縮。處理程序已釋放的記憶體,在預設啟用的 pageReporting 設定下會自動還給 Windows。5 作為檔案快取持有的分頁,以前要到虛擬機器結束才會還給 Windows。4 在現行 WSL,實驗性的 .wslconfig 設定 autoMemoryReclaim(預設是 dropCache)也會自動回收快取。5 在這個設定為 disabled、或較舊 WSL 的環境,長工作階段的快取可能一直留到虛擬機器結束,並壓迫主機記憶體。
flowchart TB
accTitle: WSL2 記憶體如何增長、收縮與歸還
accDescr: WSL2 內需求增長提高虛擬機器的記憶體用量;處理程序已釋放的分頁在預設啟用的 pageReporting 下還給 Windows;檔案快取預設由 autoMemoryReclaim 自動回收;但在停用設定或較舊 WSL 會留到虛擬機器結束,wsl --shutdown 會全部還回
grow["WSL2 內記憶體需求增長"] --> vm["vmmem 用量增長"]
vm --> freed{"那個分頁已釋放?"}
freed -->|"處理程序已釋放(pageReporting 開)"| ret["自動還給 Windows"]
freed -->|作為檔案快取持有| amr["autoMemoryReclaim 自動回收(預設)"]
amr -.-> old2["停用設定或較舊 WSL,留到虛擬機器結束"]
old2 --> sd["wsl --shutdown 全部還回"]
圖 6: 看起來「只會一直長大」的,主要是快取(以及 pageReporting 關閉時,處理程序已釋放的分頁),因此先知道歸還路徑,再判斷是不是洩漏。
若要明確上限,%UserProfile%\.wslconfig 能控制虛擬機器整體的記憶體、CPU 數與交換。5
# %UserProfile%\.wslconfig
[wsl2]
memory=8GB
processors=4
swap=2GB
變更設定後,用 wsl --shutdown 重啟虛擬機器才會生效。這種動態配置──「上限是設定,實際用量跟著需求」──在下一個題目 Windows Sandbox 還會再往前走一步。
4. Windows Sandbox ── 重用主機的 Windows
4.1. 動態基礎映像:500 MB 裡的完整 Windows
Windows Sandbox 是由 Hypervisor 隔離的一次用 Windows 桌面。關掉就全部消失;下一次從乾淨狀態在數秒內啟動。1
第一個謎是磁碟。它能啟動完整的 Windows,但 Sandbox 的基礎映像安裝後大約只有 500 MB,散佈時壓縮約 30 MB。2 秘密是動態基礎映像。
- 多數作業系統檔案不可變,因此主機上的複本可以原樣共用。
- 少數可變檔案不能共用,因此在基礎映像裡為它們保留乾淨複本。
- 啟動時,主機的不可變檔案加上可變檔案的本機複本組合起來,組出完整的 Windows 映像。2
也就是說,Sandbox 既不下載也不儲存一份 Windows 複本;它重用主機上已安裝的 Windows 來啟動。
flowchart TB
accTitle: 動態基礎映像如何組裝
accDescr: 主機 Windows 的不可變作業系統檔案被共用;只有可變檔案以乾淨複本放在基礎映像;兩者組合成 Sandbox 的完整 Windows 映像
hostw["主機的完整 Windows"] --> imm["不可變作業系統檔案(多數)"]
hostw --> mut["可變作業系統檔案(少數)"]
imm -->|原樣共用| img["Sandbox 開機映像"]
mut -->|保留乾淨複本| img
img --> boot["作為完整 Windows 開機"]
img -.-> size["只需儲存約 500 MB"]
圖 7: 放棄磁碟重複的形態,不是「再擁有另一套 Windows」,而是「從主機的 Windows 組出來」。
那份組合讓下面的生命週期成為可能。被丟掉的是 Sandbox 裡的本機狀態。若在 .wsb 組態檔把可寫資料夾從主機對應進來,那裡的變更會留在主機。6
flowchart TB
accTitle: Windows Sandbox 的生命週期
accDescr: 啟動在數秒內準備乾淨的 Windows;應用程式驗證或實驗後關掉,Sandbox 內所有狀態被丟掉,因此下一次也從乾淨開始;但對應為可寫的主機資料夾變更會留下
launch["啟動(數秒)"] --> clean["乾淨的 Windows"]
clean --> work["應用程式驗證或實驗"]
work --> close2["關閉"]
close2 --> discard["丟掉 Sandbox 內所有狀態"]
discard -.-> mapped["對應為可寫的資料夾變更留在主機"]
discard -->|下一次啟動| launch
圖 8: 每次都能回到乾淨,是因為可變部分是一次用的複本,丟掉它是設計的一部分。
4.2. Direct map:同一個 ntdll.dll 是同一個實體分頁
不只磁碟,RAM 也共用。因為 Sandbox 跑和主機相同的作業系統映像,會用稱為「direct map」的技術,讓作業系統二進位使用與主機相同的實體記憶體分頁。Sandbox 裡把 ntdll.dll 載入記憶體時,它指向主機上已載入的同一個二進位的同一個實體分頁。在不把主機秘密暴露於危險的前提下,它達到遠小於傳統虛擬機器的記憶體足跡。2
「讓數個使用者共用同一個實體分頁」──那和第 3 回記憶體系列追過的、經區段物件的 DLL 共用是同一個想法(「區段物件與 Copy-on-Write」)。那個機制是處理程序之間的共用;Sandbox 跨過虛擬機器邊界做這件事。
flowchart TB
accTitle: 經由 direct map 的實體分頁共用
accDescr: 主機上的應用程式與 Sandbox 裡的應用程式,對 ntdll 等作業系統二進位共用同一個實體記憶體分頁,降低記憶體用量
happ["主機上的應用程式"] --> hva["主機端虛擬位址"]
sapp["Sandbox 裡的應用程式"] --> sva["Sandbox 端虛擬位址"]
hva --> phys["同一個實體分頁(ntdll.dll 等作業系統二進位)"]
sva --> phys
phys -.-> save["不必重複一份作業系統份量的 RAM"]
圖 9: Direct map 是處理程序之間用過的分頁共用想法,套用到虛擬機器邊界之外。
4.3. 借還記憶體:比虛擬機器更像處理程序
相對於傳統虛擬機器的靜態記憶體配置,Sandbox 所坐的容器技術與主機合作,動態決定資源配置。主機記憶體不足時,能用收回一般處理程序記憶體的同一方式,從容器收回記憶體。2 Hyper-V Dynamic Memory 也能在設定範圍內增減虛擬機器的配置,但 Sandbox 更進一步:差別在於它和主機的記憶體管理站在同一塊場地上借還。
flowchart TB
accTitle: 主機與 Sandbox 之間的記憶體合作
accDescr: 傳統虛擬機器預設是靜態大小的獨占配置,調整手段有限;Sandbox 因應主機記憶體壓力成為回收對象,並與一般處理程序在同一塊場地上借還記憶體
pressure["主機記憶體壓力上升"] --> from{"從哪裡收回?"}
from --> proc["一般處理程序的 Working Set"]
from --> sbx["Sandbox(容器)的用量"]
proc --> relief["空閒記憶體被確保"]
sbx --> relief
relief -.-> contrast["傳統虛擬機器的調整手段有限"]
圖 10: 在記憶體的借還上,Sandbox 站在處理程序這一側而不是虛擬機器這一側,主機有困難時就交出記憶體。
第 1 回說過「虛擬機器的效能也取決於主機端」,但輕量虛擬機器再走一步:記憶體配置本身就是與主機的共同工作。Sandbox 能用「另一個應用程式」而不是「沉重虛擬化產品」的手感來使用,原因就是這份合作。
用 Sandbox 驗證業務應用程式的具體步驟,見稍早的「用 Windows 沙箱加速應用程式驗證」。本文是那底下的機制。
5. 容器 ── 隔離線畫在哪裡
5.1. 處理程序隔離與 Hyper-V 隔離
Windows 容器在執行期有兩種隔離模式。映像共用;啟動時用旗標選擇。7
- 處理程序隔離:數個容器與主機共用核心,並透過檔案系統、登錄檔、網路連接埠、處理程序識別碼空間、Object Manager 命名空間等每個命名空間的虛擬化來隔離。本質上與 Linux 容器同一做法。
- Hyper-V 隔離:每個容器跑在高度最佳化的虛擬機器裡,並有實際上專用的核心。虛擬機器的存在,在容器與主機之間放進硬體層級的隔離。7
經命名空間的隔離,可以說成登錄檔虛擬化文章(「Windows 上的登錄重新導向與虛擬化」)見過的技術──「在同一個 API 下秀出不同現實」──做到徹底的版本。
flowchart TB
accTitle: 處理程序隔離與 Hyper-V 隔離
accDescr: 處理程序隔離下,容器與主機共用核心並經命名空間隔離;Hyper-V 隔離下,每個容器在最佳化虛擬機器裡有專用核心
subgraph pi ["處理程序隔離"]
c1["容器 A"] --> sk1["與主機共用的核心"]
c2["容器 B"] --> sk1
end
subgraph hi ["Hyper-V 隔離"]
c3["容器 C"] --> k3["專用核心(最佳化虛擬機器裡)"]
c4["容器 D"] --> k4["專用核心(最佳化虛擬機器裡)"]
end
sk1 ~~~ c3
圖 11: 即使是同一份容器映像,隔離線畫在核心上面,還是把核心本身切開,是啟動時做的選擇。
5.2. 哪一種能稱為「安全性邊界」
這兩種模式的差別不只是效能故事。Microsoft 不把處理程序隔離容器當成穩固的安全性邊界。被作為安全性邊界維護(含漏洞回應)的容器是 Hypervisor 隔離容器,在敵對多租戶情境應選擇 Hyper-V 隔離。8
第 2 回看過的 VBS 也是假設「核心可能被突破」、退到 Hypervisor 邊界的設計。同一準則適用於容器世界。圈住不受信任程式碼的線,畫在 Hypervisor 邊界,而不是共用核心的內側。
flowchart TB
accTitle: 依對程式碼的信任程度選擇隔離
accDescr: 若工作負載可信,用處理程序隔離換密度與效能;若程式碼不受信任或是別人的,選擇 Hypervisor 邊界,例如 Hyper-V 隔離容器、停用網路的強化 Windows Sandbox,或隔離的虛擬機器
trust{"能信任那段程式碼嗎?"} -->|能| dens["處理程序隔離(優先密度與速度)"]
trust -->|不能/別人的程式碼| bound["選擇 Hypervisor 邊界"]
bound --> opt1["Hyper-V 隔離容器"]
bound --> opt2["強化的 Sandbox 或隔離虛擬機器"]
圖 12: 隔離模式首先是安全性故事,其次才是效能故事,信任決定線畫在哪。
順便一提,在 Hyper-V 虛擬機器裡跑 Hyper-V 隔離容器,會讓 Hypervisor 疊兩層──巢狀虛擬化。符合條件的環境(Intel 處理器搭配 Windows 10 / Windows Server 2016 或更新的主機,或 AMD 處理器搭配 Windows 11 / Windows Server 2022 或更新的主機,以及各自對應的虛擬機器組態版本)上,一層巢狀在正式環境受支援,進一步前提是把虛擬化擴充暴露給外層虛擬機器的設定(Hyper-V 上 Set-VMProcessor 的 ExposeVirtualizationExtensions)。在虛擬機器裡跑 WSL2 同樣受支援。9 能否在雲端開發虛擬機器裡用 WSL2 或 Docker,也取決於那個虛擬機器大小與組態是否暴露巢狀虛擬化。
flowchart TB
accTitle: 巢狀虛擬化的結構
accDescr: 雲端虛擬機器坐在實體主機的 Hypervisor 上,其中再跑另一個 Hypervisor(受支援的巢狀是一層)以支援 WSL2 與 Hyper-V 隔離容器
phys3["實體主機的 Hypervisor"] --> cvm["雲端虛擬機器(開發機)"]
cvm --> nhv["虛擬機器裡的 Hypervisor(巢狀第 1 層)"]
nhv --> w2["WSL2"]
nhv --> hvc["Hyper-V 隔離容器"]
nhv -.-> limit["受支援的巢狀是一層"]
圖 13: 雲端虛擬機器裡 wsl 能跑的原因,是巢狀虛擬化官方只支援一層。
5.3. 隔離與輕的光譜
把到目前的角色排在同一條軸上,看起來是這樣。
flowchart TB
accTitle: 隔離強度與輕的光譜
accDescr: 處理程序隔離容器最輕但共用核心;WSL2、Sandbox 與 Hyper-V 隔離容器是具備專用核心的輕量虛擬機器(Sandbox 用共用變輕,WSL2 用專用核心變輕);完整虛擬機器最重但通用
ax["輕 ← → 重"] ~~~ p1
p1["處理程序隔離容器(共用核心)"] --> p2["WSL2/Sandbox/HV 隔離(輕量 VM)"]
p2 --> p3["完整虛擬機器(什麼都能跑;持有完整複本)"]
p1 -.-> n1["邊界:命名空間"]
p2 -.-> n2["邊界:Hypervisor"]
p3 -.-> n3["邊界:Hypervisor+完整獨立"]
圖 14: 輕量虛擬機器群是守住 Hypervisor 邊界並切掉重複的中間解;切法分成 Sandbox 的共用與 WSL2 的專用核心。
6. 自己看一看
輕與共用,可以在眼前的機器上觀察。
啟動時間與記憶體的起伏(WSL2)。打開工作管理員,試下面這些。
# Felt startup time (the first run starts the VM; the second and later are faster still)
Measure-Command { wsl -e true }
# Memory usage of the WSL2 VM (vmmem / Virtual Machine Memory)
Get-Process -Name vmmem* | Select-Object Name, WorkingSet64
# End the whole VM and watch the memory come back
wsl --shutdown
若在 WSL2 裡做大型建置或檔案操作,vmmem 會增長,你能觀察它被 wsl --shutdown 一次還回。
檔案放哪裡造成的速度差(WSL2)。把同一個儲存庫放在 Linux 端(~/repo)與 Windows 端(/mnt/c/repo),比較 git status 或解壓縮的時間,第 3.2 節的差異就會變成數字。
Direct map 的背景(Sandbox)。啟動 Sandbox,看主機工作管理員裡記憶體的增量。增量遠小於「另一套 Windows」會讓你想像的,就是共用在說話。要再往下挖主機端記憶體分解,涵蓋 RAMMap 與 VMMap 用法的 Sysinternals 工具文章(「Process Explorer / Handle / VMMap 實戰」)有用。不過這些是看主機端處理程序與實體記憶體分類的工具;它們不直接觀察與客體本身的共用。
容器隔離模式(Docker / Windows 容器)。若有 Windows 容器環境,用 docker run --isolation=process 與 --isolation=hyperv 啟動同一映像,比較啟動時間與在工作管理員裡的樣子(處理程序隔離下,容器內的處理程序會出現在主機的處理程序清單),就能感覺隔離線坐在哪。7 不過處理程序隔離的前提是主機與映像版本相符,在用戶端作業系統上限於開發與測試用途。Hyper-V 隔離允許較寬的組合,因此請在相容的一對上比較。10
7. 實務上要避開的三種誤讀
7.1. 「WSL2 很慢」
慢的不是 WSL2,而是跨越作業系統邊界的檔案 I/O 路徑。很多情況只要把專案移到 Linux 端,手感就變成另一件事。4 反過來說,把 Windows 工具會碰到的檔案放在 Linux 端,同樣因為同一理由而不利。用「放在使用它的那一端所在的作業系統」來判斷。
7.2. 「vmmem 變很大就是記憶體洩漏」
WSL2 記憶體隨需求增長與收縮,已釋放的部分會被還回。在現行 WSL,檔案快取也由 autoMemoryReclaim(預設是 dropCache)自動回收,因此「一直很大」常常過一段時間就解消。5 若仍留下,確認 autoMemoryReclaim 沒有被設成 disabled,以及負責還回已釋放部分的 pageReporting 沒有被關掉(或你不是較舊 WSL),然後用 .wslconfig 的 memory 明確上限,或在工作階段邊界用 wsl --shutdown 全部還回。分辨洩漏與不是洩漏的想法,和記憶體系列入門回「Windows 的「記憶體使用量」代表什麼?」相同。
7.3. 「在容器裡,所以安全」
處理程序隔離容器共用核心,依 Microsoft 的準則它不是安全性邊界。8 要跑不受信任的程式碼或檢體,選擇具有 Hypervisor 邊界的隔離,例如 Hyper-V 隔離容器、Windows Sandbox,或專用虛擬機器。不過 Hypervisor 邊界不是全面免責。Windows Sandbox 的預設設定啟用網路連線,可能把不受信任的應用程式暴露給內部網路。1 若用來跑檢體,在 .wsb 組態檔停用網路與剪貼簿重新導向以加強隔離,或使用隔離網路上的專用虛擬機器。
8. 總結 ── 為系列收尾
第 3 回的重點。
- 輕量虛擬機器的輕,是「停掉重複」的結果,不是「削弱隔離」。
- WSL2 在受管理的輕量公用虛擬機器裡跑真正的 Linux 核心,發行版在該虛擬機器裡作為容器隔離。3 效能規則是把檔案放在使用它的作業系統,記憶體動態增減,上限可在
.wslconfig控制。45 - Windows Sandbox 經動態基礎映像共用主機不可變的作業系統檔案,並經 direct map 共用目標作業系統二進位的實體分頁,因此不持有完整 Windows 的複本。2 可變檔案仍需要約 500 MB,加上裡面跑的應用程式的記憶體。
- 容器隔離模式在啟動時選擇,能稱為安全性邊界的那一側是 Hyper-V 隔離。78
若把整個系列放在一頁,看起來是這樣。
- 第 1 回:Windows 底下有一層 Hypervisor,主機作業系統本身作為根分割區執行。CPU 與記憶體(SLAT)的仲裁由這一層直接做,合成裝置的 I/O 由 VMBus 另一端的根分割區(VSP)仲介。
- 第 2 回:那一層不只用來把虛擬機器彼此隔離,也用來在同一個作業系統裡畫出比核心更強的邊界(VTL)。Windows 11 的預設安全性建立在這上面。
- 第 3 回:在同一層上,切掉重複讓「數秒啟動的虛擬機器」成為可能。隔離線被守住,它已變成日常工具。
flowchart TB
accTitle: 整個系列的一張圖
accDescr: 直接在硬體上的 Hypervisor 是第 1 回;主機 Windows 裡 VTL0 與 VTL1 的分裂是第 2 回;同一層上 WSL2、Sandbox 與 Hyper-V 隔離的輕是第 3 回;處理程序隔離容器共用主機核心;Sandbox 用共用變輕,WSL2 用專用核心變輕
hw3["硬體"] --> hv3["Hypervisor(第 1 回)"]
hv3 --> rp3["主機 Windows(VTL 隔離是第 2 回)"]
hv3 --> lw3["WSL2、Sandbox、Hyper-V 隔離(第 3 回)"]
rp3 --> pc3["處理程序隔離容器(共用核心)"]
lw3 -.-> mech3["Sandbox 共用;WSL2 用專用核心變輕"]
圖 15: 把三回疊起來,就是現行 Windows 脚下地面的全貌。
虛擬化不再是機房技術,也不再只是給把虛擬機器拉起來的人用的技術。在你 Windows 脚下的地面,它安靜地同時支撐安全性與開發體驗──我們現在就在那裡。
相關文章
- Windows 虛擬化的深層(第 1 回)── 你的 Windows 其實跑在哪裡?Hypervisor 與分割區
- Windows 虛擬化的深層(第 2 回)── 連核心都看不到的記憶體:VBS、HVCI 與 Credential Guard 如何運作
- The Depths of Windows Memory (Part 3) — Section Objects and Copy-on-Write: What DLLs and File Mappings Really Are
- 用 Windows 沙箱加速 Windows 應用程式開發的驗證 - 以實務向整理管理員權限問題、乾淨環境、權限不足・資源不足的重現
- 登錄檔的 32bit/64bit 重新導向與虛擬化的陷阱 ── Wow6432Node 與「明明寫入了卻讀不到值」的問題
相關諮詢領域
小村軟體有限公司承接使用 WSL2 與容器的開發環境建置、Windows 應用程式驗證環境設計,以及虛擬化環境中的效能與相容性調查。
參考連結
-
Microsoft Learn, Windows Sandbox. 關於 Windows Sandbox 作為一次用虛擬機器在數秒內啟動,關閉時丟掉一切;用 Microsoft Hypervisor 跑分開的核心以與主機隔離;以及網路連線預設啟用,可在組態檔停用。 ↩ ↩2 ↩3
-
Microsoft Learn, Windows Sandbox architecture. 關於動態基礎映像從共用主機不可變作業系統檔案加上可變檔案的乾淨複本,組出完整 Windows 映像(安裝後約 500 MB);相對於傳統虛擬機器的靜態記憶體配置,容器與主機合作動態配置,因此主機能收回記憶體;以及 direct map 讓 ntdll.dll 等作業系統二進位使用與主機相同的實體分頁。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, What is the Windows Subsystem for Linux?. 關於 WSL2 在輕量公用虛擬機器裡跑 Linux 核心;各發行版作為隔離容器執行,共用網路命名空間與核心,同時分開 PID、掛載、使用者等命名空間。 ↩ ↩2 ↩3
-
Microsoft Learn, Comparing WSL Versions. 關於 WSL2 核心由 Microsoft 從 Stable 分支打造;Store 散佈的 WSL 以與作業系統映像分離的套件接收更新,用
wsl --update套用(較舊的內建散佈則經 Windows Update);解 tar 最高約 20 倍等效能例子;跨作業系統檔案系統效能 WSL1 較快,因此檔案應放在使用它的作業系統;以及記憶體隨已釋放部分歸還而增減,快取可能要到虛擬機器結束才還回。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 -
Microsoft Learn, Advanced settings configuration in WSL. 關於能在 .wslconfig 的 [wsl2] 區段設定 WSL2 虛擬機器整體的記憶體上限、處理器數、交換與 pageReporting(預設啟用;負責偵測並還回未使用記憶體);以及實驗性設定 autoMemoryReclaim 預設為 dropCache,因此快取記憶體會自動回收。 ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Use and configure Windows Sandbox. 關於 .wsb 組態檔的 MappedFolders 能以唯讀或可寫共用主機資料夾。 ↩
-
Microsoft Learn, Isolation Modes. 關於 Windows 容器的處理程序隔離與主機共用核心並經命名空間隔離;Hyper-V 隔離在最佳化虛擬機器裡有實際上專用的核心;以及同一映像可在啟動時用旗標以任一模式執行。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Secure Windows containers. 關於只有 Hypervisor 隔離容器被當成安全性邊界;處理程序隔離容器不被當成穩固的安全性邊界;以及敵對多租戶情境應選擇 Hypervisor 隔離。 ↩ ↩2 ↩3
-
Microsoft Learn, What is Nested Virtualization?. 關於在 Hyper-V 虛擬機器裡跑 Hyper-V 隔離容器(一層巢狀)在正式環境受支援;需求是 Intel 處理器搭配 Windows Server 2016 / Windows 10 或更新,或 AMD 處理器搭配 Windows Server 2022 / Windows 11 或更新,加上各自對應的虛擬機器組態版本;把虛擬化擴充暴露給外層虛擬機器(ExposeVirtualizationExtensions)是前提;以及在 Hyper-V 虛擬機器裡跑 WSL2 受支援。 ↩
-
Microsoft Learn, Windows container version compatibility. 關於處理程序隔離的前提是主機與容器映像版本相符;Hyper-V 隔離能跑與主機不同作業系統版本的映像;以及用戶端作業系統上的處理程序隔離限於開發與測試用途。 ↩
相關文章
共用相同標籤的最新文章。能以相近的主題延伸理解。
Windows 虛擬化的深層(第 1 回)── 你的 Windows 其實跑在哪裡?Hypervisor 與分割區
啟用 Hyper-V 後,主機 Windows 本身會以根分割區的身分跑在 Hypervisor 之上。本文從 VT-x、SLAT、VMBus 的角色解說虛擬化的基礎。
Windows 虛擬化的深層(第 2 回)── 連核心都看不到的記憶體:VBS、HVCI 與 Credential Guard 如何運作
在相容硬體上全新安裝時,VBS 預設啟用,並用 Hypervisor 與 SLAT 做出比核心更強的隔離。本文解說 VTL、Secure Kernel、HVCI 與 Credential Guard 的結構。
用 Windows 沙箱加速 Windows 應用程式開發的驗證 - 以實務向整理管理員權限問題、乾淨環境、權限不足・資源不足的重現
整理在 Windows 應用程式開發中如何運用 Windows Sandbox 加速驗證的實務做法。透過按情境分檔的 .wsb、唯讀輸入與專用 Outbox 寫入分離、在容器內另建標準使用者重現權限不足、以及降低記憶體和關閉 vGPU 製造資源不足偏向,把每次的乾淨環境準備...
Win32 執行緒集區 API ── 用 CreateThreadpoolWork 做「不自己建立執行緒」的並行
原生程式碼裡到處呼叫 CreateThread 嗎?本文依一次資訊解說 Vista 重新設計的 Win32 執行緒集區 API──work、timer、wait、io 四種物件、清理群組,以及回呼裡不該做的事。
具名管道實務 ── 從設計到安全性,整理 Windows 的標準 IPC
以實務角度解說 Windows 標準行程間通訊──具名管道。從一次資訊整理位元組/訊息模式的選擇、同時服務多個用戶端的伺服器設計、ACL 與偽裝的安全性,以及 .NET 的具名管道串流。
相關主題
與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。
Windows 技術主題
彙整 KomuraSoft LLC 關於 Windows 開發、故障調查與既有資產活用文章的主題中心。
常見問題
整理諮詢這個主題時常見的問題。
- WSL2 是虛擬機器嗎?
- 是。WSL2 在輕量公用虛擬機器裡跑 Microsoft 打造的真正 Linux 核心。虛擬機器由 WSL 在幕後管理,設計上從不讓使用者去想虛擬機器設定或等待開機。每個 Linux 發行版在這個受管理的虛擬機器裡,作為隔離容器執行。
- 為什麼 WSL2 裡 /mnt/c 底下的檔案操作很慢?
- 因為從 WSL2 的 Linux 核心存取 Windows 端檔案系統,要經過跨越作業系統邊界的檔案共用。對 Linux 檔案系統(ext4 虛擬磁碟)的操作是快的,因此規則是:把專案檔案放在操作它們的工具所在的同一作業系統端。
- vmmem 處理程序記憶體用量很大,是洩漏嗎?
- 多數情況不是洩漏。WSL2 記憶體隨使用增長與收縮,處理程序已釋放的記憶體在預設啟用的 pageReporting 設定下會還給 Windows。檔案快取分頁也由現行 WSL 經 .wslconfig 的 autoMemoryReclaim(預設是 dropCache)自動回收。在這些設定被停用、或較舊 WSL 的環境,記憶體可能一直留到虛擬機器結束;那時用 memory 設定上限,或用 wsl --shutdown 還回去。
- Windows Sandbox 怎能用幾百 MB 磁碟就啟動完整的 Windows?
- 靠稱為動態基礎映像的機制。它共用主機上已安裝 Windows 裡不可變的作業系統檔案,只對少數可變檔案保留乾淨複本。這樣就能組出可開機的完整映像,而不必儲存一份完整的 Windows 複本。
- 容器比虛擬機器更安全嗎?
- 取決於隔離模式。處理程序隔離容器與主機共用核心,Microsoft 不把這當成穩固的安全性邊界。處理敵對程式碼時,需要 Hyper-V 隔離,讓每個容器有自己專用的核心。