Hyper-V Server 2012 R2の仮想マシンが使用できるメモリーサイズは、実空きメモリーサイズより更に小さくなります。
どの程度のオーバーヘッドかかかるのかの解説が KB として出ています。
Hyper-V にてメモリ空き容量があるにも関わらず仮想マシンの起動に失敗する
http://support.microsoft.com/kb/2962295/ja
いったいどの程度のメモリーが仮想マシンに割り当て可能なのかの計算を PowerShell でしてみましょう。
#総メモリーサイズ $TotalMemory = 0 Get-WmiObject -Class Win32_PhysicalMemory | % {$TotalMemory += $_.Capacity} # 空きメモリーサイズ $Counter = Get-counter -Counter "\Memory\Available Bytes" $FreeMemory = $Counter.CounterSamples.CookedValue # 最初の8GBオーバーヘッド $First8GB = 8GB/32 # 残りメモリーサイズのオーバーヘッド $Other8GB = ($TotalMemory - 8GB)/128 # OS予約メモリーサイズ $OSReserveMemory = ($First8GB + $Other8GB) * 2 + 1432MB # VM 使用可能メモリーサイズ $UseableVMMemory = $FreeMemory - $OSReserveMemory # GB表示 "Total memory size can be assigned to the VM = {0} GB" -f ($UseableVMMemory / 1GB) |
これで計算することができます。
Hyper-Vの役割が入っているHyper-V Server 2012 R2では、Hyper-Vのパフォーマンスカウンターで仮想マシンに割り当て可能なメモリーサイズを確認することができます。
# 割り当て可能メモリーサイズを実際に聞いてみる $Counter = Get-counter -Counter "\hyper-v dynamic memory balancer(system balancer)\available memory" $VMMem = $Counter.CounterSamples.CookedValue "Hyper-V available memory = {0} GB" -f ($VMMem * 1MB / 1GB) # 割り当て済みメモリーサイズと合算して、トータル割り当て可能メモリーサイズを算出する $MemoryAssigned = 0 Get-VM | % { $MemoryAssigned += $_.MemoryAssigned} "Total memory size can be assigned to the VM = {0} GB" -f (($VMMem * 1MB / 1GB) + ($MemoryAssigned / 1GB)) |
KBにある回避策がどの程度効果があるのかですね。
MemoryReserveの最小値は411なのですが、小さな値をセットしてもあまり意味はありません。(1024とかで十分)
MemoryReserveは、Hyper-Vが計算して、VM起動可能かの事前チェック(\hyper-v dynamic memory balancer(system balancer)\available memory)を騙すだけで、OSが確保済みのメモリーを解放してVMに与えるものではないです。
VM起動時には、OSが確保しているメモリーはそのまま維持され、VMが要求するメモリーをHyper-Vがかき集めてVMに渡します。メモリーの固定割り当ての場合、VMの起動プロセスで要求されたメモリー確保が出来なかった場合VM起動が失敗します。
VM起動が成功した後にホストOS内で追加メモリー要求が発生しなければ普通に動作しますが、追加メモリー要求が発生した場合にはホストOSがメモリー不足となり、不安定になったり仮想マシンのスローダウンに至ってしまいます。
MemoryReserveを設定すると、空きメモリーの全てが仮想マシン割り当てられるわけではなく、仮想マシン起動に必要なオーバーヘッドが必要で、試行錯誤してみると、このオーバーヘッドは530MBくらいのようです。
MemoryReserveの使用は非推奨になっているので、使用する際は自己責任で
おまけで、今回MemoryReserveを色々設定するのに使ったSetMemoryReserve.ps1です。
< SetMemoryReserve.ps1 >
param ( [String]$Switch ) $Num = $null # 照会の時 if( $Switch -match "Sh" ){ $Mode = "Show" } elseif( $Switch -ne "" ){ $Num = $Switch -as [int] # 数値のとき if( $Num -ne $null ){ $MemorySize = $Num if( $Num -eq 0 ){ $Mode = "Remove" } else{ $Mode = "Update" } } # 数値以外の時 else{ echo "input `"Show`" or Numeric(MB)" exit } } # 引数がなかった時 else{ echo "input `"Show`" or Numeric(MB)" exit } $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization" $RegKey = "MemoryReserve" # キーの有無確認( Read系なので Try でトラップできない orz) $SetedMemorySize = Get-ItemProperty $RegPath -name $RegKey # キーがなかった時 if( -not $? ){ # 照会の時はキーなし if( $Mode -eq "Show" ){ echo "Key not found" } else{ # 削除の時は処理不要 if( $Mode -eq "Remove" ){ echo "Not need Remove" } # 更新 else{ # キーを追加する New-ItemProperty $RegPath -name $RegKey -PropertyType DWord -Value $MemorySize $SetedMemorySize = Get-ItemProperty $RegPath -name $RegKey $h = $SetedMemorySize.MemoryReserve echo "Set OS Reserved Memory is $h MB" } } } # キーがあったとき else{ # 照会の時 if( $Mode -eq "Show" ){ # 設定されていたメモリーサイズ表示 $h = $SetedMemorySize.MemoryReserve echo "OS Reserved Memory is $h MB" } # 更新の時 else{ # 削除 if( $Mode -eq "Remove" ){ Remove-ItemProperty $RegPath -name $RegKey echo "Removeed" } # 更新 else{ # キーを更新する Set-ItemProperty $RegPath -name $RegKey -Value $MemorySize $SetedMemorySize = Get-ItemProperty $RegPath -name $RegKey $h = $SetedMemorySize.MemoryReserve echo "Set OS Reserved Memory is $h MB" } } } |
Hyper-V server 2012 R2 の目次に戻る
http://www.vwnet.jp/Windows/etc.asp#Hyper-V_server_2012_R2
Copyright © MURA All rights reserved.