【发布时间】:2012-09-24 08:24:15
【问题描述】:
我有一个很奇怪的问题;在我们的 REST 应用程序中,我们引入了一个用于上传 WebPackage 的选项。由于这些在解压后可能会相当大,因此我们希望确保通过 MemoryFailPoint 进行内存检查的成功体验。
在我的本地 IIS 7.5 上,这可以完美运行 - 甚至可以达到最大值。预期值为 2GB。 在我们的带有 IIS 7.5 的虚拟 Windows Server 2008R2 x64 上,这无条件失败 - 即使只尝试 1MB。
虚拟服务器托管在 VMWare ESXi 4.1.0, 348481 上。
这是在虚拟机上失败的示例代码:
using (MemoryFailPoint failPoint = new MemoryFailPoint(1))
{
... // deliberately excluded webpackage code
}
还有异常(在 XML 中):
<InsufficientMemoryException>
<Message>Insufficient memory to meet the expected demands of an operation, and this system is likely to never satisfy this request. If this is a 32 bit system, consider booting in 3 GB mode.</Message>
<StackTrace>
<Line>at System.Runtime.MemoryFailPoint..ctor(Int32 sizeInMegabytes)</Line>
<Line>at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)</Line>
<Line>at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)</Line>
<Line>at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)</Line>
<Line>at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)</Line>
<Line>at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</Line>
</StackTrace>
<UserDefinedInformation>
<failpointSizeInMegaBytes>1.00</failpointSizeInMegaBytes>
<gcTotalMemoryBeforeInMegaBytes>153.34</gcTotalMemoryBeforeInMegaBytes>
</UserDefinedInformation>
</InsufficientMemoryException>
还有一个来自我机器的类似异常 - 请注意,我需要分配 64GB 在之前我可能会触发异常:
<InsufficientMemoryException>
<Message>Insufficient available memory to meet the expected demands of an operation at this time. Please try again later.</Message>
<StackTrace>
<Line>at System.Runtime.MemoryFailPoint..ctor(Int32 sizeInMegabytes)</Line>
<Line>at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)</Line>
<Line>at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)</Line>
<Line>at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)</Line>
<Line>at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)</Line>
<Line>at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</Line>
</StackTrace>
<UserDefinedInformation>
<failpointSizeInMegaBytes>65536.00</failpointSizeInMegaBytes>
<gcTotalMemoryBeforeInMegaBytes>150.63</gcTotalMemoryBeforeInMegaBytes>
</UserDefinedInformation>
</InsufficientMemoryException>
这让我发疯......真的......但是嘿;注意两个(非常)不同的例外:
服务器:内存不足以满足操作的预期需求,并且该系统可能永远无法满足该请求。如果这是 32 位系统,请考虑以 3 GB 模式启动。
使用 Jetbrains 的 dotPeek 和这个网站 http://reflector.webtropy.com/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/Runtime/MemoryFailPoint@cs/1305376/MemoryFailPoint@cs,我们可以看到可能是什么问题(尽管我仍然一无所知):
// Check to see that we both have enough memory on the system
// and that we have enough room within the user section of the
// process's address space. Also, we need to use the GC segment
// size, not the amount of memory the user wants to allocate.
// Consider correcting this to reflect free memory within the GC
// heap, and to check both the normal & large object heaps.
ulong num1 = (ulong) sizeInMegabytes << 20;
this._reservedMemory = num1;
ulong size = (ulong)(Math.Ceiling((double)num1 / (double)MemoryFailPoint.GCSegmentSize) * (double)MemoryFailPoint.GCSegmentSize);
if (size >= MemoryFailPoint.TopOfMemory)
throw new InsufficientMemoryException(Environment.GetResourceString("InsufficientMemory_MemFailPoint_TooBig"));
本地:目前没有足够的可用内存来满足操作的预期需求。请稍后再试。
编辑
Hans 和我讨论了 VM 大小,但由于我现在得出结论,它在开发服务器和我的机器上或多或少是相等的,所以我现在将这部分排除在外。任何提示、建议等都非常受欢迎。
流程信息
Process Name: w3wp
PID: 5716
User Name: NT AUTHORITY\NETWORK SERVICE
Working Set: 376.456 K
Peak Working Set: 432.400 K
Private Working Set: 320.684 K
Commit Size: 538.552 K
Handles: 919
Threads: 39
操作系统 (WMI)
BootDevice: \Device\HarddiskVolume1
BuildNumber: 7601
BuildType: Multiprocessor Free
Caption: Microsoft Windows Server 2008 R2 Standard
CodeSet: 1252
CountryCode: 45
CreationClassName: Win32_OperatingSystem
CSCreationClassName: Win32_ComputerSystem
CSDVersion: Service Pack 1
CSName: SOME_NAME [MODIFIED]
CurrentTimeZone: 120
DataExecutionPrevention_32BitApplications: True
DataExecutionPrevention_Available: True
DataExecutionPrevention_Drivers: True
DataExecutionPrevention_SupportPolicy: 3
Debug: False
Description: Development Server
Distributed: False
EncryptionLevel: 256
ForegroundApplicationBoost: 2
FreePhysicalMemory: 5.366.516 K
FreeSpaceInPagingFiles: 8.368.456 K
FreeVirtualMemory: 12.985.412 K
InstallDate: 17-01-2011 15:01:55
LargeSystemCache: null
LastBootUpTime: 11-09-2012 14:44:33
LocalDateTime: 03-10-2012 14:13:47
Locale: 0406
Manufacturer: Microsoft Corporation
MaxNumberOfProcesses: 4294967295
MaxProcessMemorySize: 8.589.934.464 K
MUILanguages: System.Object[]
Name: Microsoft Windows Server 2008 R2 Standard |C:\Windows|\Device\Harddisk0\Partition2
NumberOfLicensedUsers: null
NumberOfProcesses: 70
NumberOfUsers: 7
OperatingSystemSKU: 7
Organization:
OSArchitecture: 64-bit
OSLanguage: 1033
OSProductSuite: 272
OSType: 18
OtherTypeDescription: null
PAEEnabled: null
PlusProductID: null
PlusVersionNumber: null
Primary: True
ProductType: 3
RegisteredUser: Windows User
SerialNumber: 11111-111-1111111-11111 [MODIFIED]
ServicePackMajorVersion: 1
ServicePackMinorVersion: 0
SizeStoredInPagingFiles: 8.388.152 K
Status: OK
SuiteMask: 272
SystemDevice: \Device\HarddiskVolume2
SystemDirectory: C:\Windows\system32
SystemDrive: C:
TotalSwapSpaceSize: null
TotalVirtualMemorySize: 16.774.452 K
TotalVisibleMemorySize: 8.388.152 K
Version: 6.1.7601
WindowsDirectory: C:\Windows
来自开发服务器的 VMMap 屏幕截图
对虚拟大小感到好奇,我从 Sysinternals 下载了 VMMap:http://technet.microsoft.com/en-us/sysinternals/dd535533
来自我的本地计算机的 VMMap 屏幕截图(MemoryFailPoint 按预期工作)
我仍然不清楚 MemoryFailPoint 失败的原因 - 确保有足够的内存用于操作很重要(尤其是在谈论 Windows Azure 或其他云提供商时)。举个例子,由于资源非常有限,ExtraSmall 实例将在进程的某个地方失败(即使它是 x64 架构) - 这可以通过 MemoryFailPoint 阻止,从而确保数据的有效状态。
非常感谢任何帮助。
【问题讨论】:
-
这是一个非常粗略的测试。记录您在 Process Explorer 中看到的内存使用情况。至少 VM 大小和提交大小。
-
我不知道你所说的粗制是什么意思,但我现在已经添加了更多的细节——它应该可以满足。但是,我看不出关于 1MB MemoryFailPoint 的意义 :-)
-
看不到最重要的 VM 大小。这个问题表明asp.net积极保留VM:stackoverflow.com/questions/355934/…
-
网络应用程序。如果我不使用 MemoryFailPoint 就可以正常工作——即使它需要消耗 2GB 的 RAM。我下载了您推荐的 Process Explorer 并添加了“虚拟大小”列;这是一个 18GB 的内存。
-
这就是它的原因。顺便说一句,在 64 位模式下运行时使用 MemoryFailPoint 没什么意义。
标签: .net iis memory-management clr vmware