7

非常に奇妙な問題があります。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[]&amp; outputs)</Line>
        <Line>at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)</Line>
        <Line>at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)</Line>
        <Line>at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; 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[]&amp; outputs)</Line>
        <Line>at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)</Line>
        <Line>at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)</Line>
        <Line>at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)</Line>
        <Line>at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</Line>
    </StackTrace>
    <UserDefinedInformation>
        <failpointSizeInMegaBytes>65536.00</failpointSizeInMegaBytes>
        <gcTotalMemoryBeforeInMegaBytes>150.63</gcTotalMemoryBeforeInMegaBytes>
    </UserDefinedInformation>
</InsufficientMemoryException>

これは私を夢中にさせています..本当に..しかしねえ; 2 つの (非常に) 異なる例外に注意してください。

サーバー:予想される操作の要求を満たすにはメモリが不足しており、このシステムはこの要求を満たすことはほとんどありません。これが 32 ビット システムの場合は、3 GB モードで起動することを検討してください。

Jetbrains の dotPeek とこの Web サイト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 スクリーンショット

VMMap

仮想サイズに興味があるので、Sysinternals から VMMap をダウンロードします: http://technet.microsoft.com/en-us/sysinternals/dd535533

VMMap のローカル マシンのスクリーンショット (MemoryFailPoint が期待どおりに機能する場所)

VMマップ2

なぜ MemoryFailPoint が失敗するのかはまだはっきりしていません。操作に十分なメモリがあることを確認することが重要です (特に Windows Azure や他のクラウド プロバイダーと話す場合)。例を挙げると、リソースが非常に限られているため、ExtraSmall インスタンスは (x64 アーキテクチャであっても) プロセスのどこかで失敗します。これは MemoryFailPoint によって防ぐことができるため、データの有効な状態が保証されます。

どんな助けでも大歓迎です。

4

2 に答える 2

5

.net 4.5 および IIS にはバグ (または機能) があります。

MemoryFailPoint クラスは内部 GC 関連の変数に依存しますが、x64 ではこの変数は 0 になる可能性があり、ゼロで割ると正の無限大 (double) が生成され、この極値を使用する一部の演算 (ゼロで乗算することも) によって大きな double 値が生成される可能性があります (実際の FPU 設定に依存します)。

このバグは非常に簡単に確認できます。簡単な Web アプリケーションを作成し、ページを追加してから、次のコードを貼り付けます。

<%
    var memoryFailPointType = typeof(System.Runtime.MemoryFailPoint);
    var staticPrivateFieldFlags = 
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Static;
    var gCSegmentSizeField = memoryFailPointType
        .GetField("GCSegmentSize", staticPrivateFieldFlags);
    var gCSegmentSize = (uint)gCSegmentSizeField.GetValue(null);
    string allocationResult;
    try
    {
        using (var mfp = new System.Runtime.MemoryFailPoint(1))
        {
            allocationResult = "Ok";
        }
    }
    catch (Exception exception)
    {
        allocationResult = exception.Message;
    }
%>
<%= gCSegmentSize %><br /> <!-- it can be 0 -->
<%= allocationResult %><br /> <!-- 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. -->

したがって、gCSegmentSize がゼロで、(ulong)(double.PositiveInfinite * (uint)0) が 0 でない場合は、MemoryFailPoint クラスを使用しないでください。

コンソール アプリケーションでは FPU 制御ワードは 0x09001F ですが、IIS では FPU 制御ワードは 0x08001F です。

于 2012-11-03T23:13:51.040 に答える
1

.NET 4.5 のホットフィックス ロールアップ 2828842 で、この問題に対する修正を利用できます http://support.microsoft.com/kb/2828842/en-us

于 2013-05-11T00:04:53.193 に答える