内存不足?简单的方法来增加程序的可用内存

转自 https://blogs.msdn.microsoft.com/calvin_hsia/2010/09/27/out-of-memory-easy-ways-to-increase-the-memory-available-to-your-program/

当您运行VB或C#应用程序时,即使您的  计算机有很多  内存,也可能会出现OutOfMemoryException 。

 

每32位进程有一个2 ^ 32位(4 Gig)地址空间。这意味着每个指针的大小都是32位(4个字节),因此被限制为40亿个。

 

这相当于说车牌号由6位数组成,因此有100万个可能的号码。

 

4 Gigs分为一半:用户应用程序获取下半部分,操作系统获取上半部分。(这个界限可以改变:见下文)。

 

启动VS 2010. File-> New-> Project-> VB或C#Windows WPF应用程序。

粘贴下面的VB或C#代码。它创建一个堆,然后在循环中连续分配100Meg的内存,直到引发异常。

 

在我的具有8G内存的64位Windows 7机器上(你的数码相机或手机可能有  更多的内存!),我在分配之前分配了大约1.4Gig的内存。

 

#10 1,048,576,000

#11,153,433,600

#12 1,258,291,200

#13 1,363,148,800

类型'System.OutOfMemoryException'的异常异常被抛出。

 

 

现在选择Project-> Properties-> Compile-> Build Events-> PostBuildEvent Command,并  添加这两行

调用“$(DevEnvDir).. \ .. \ vc \ vcvarsall.bat”x86

“$(DevEnvDir).. \ .. \ vc \ bin \ EditBin.exe”“$(TargetPath)”   / LARGEADDRESSAWARE

 

注意:报价的位置非常重要

第一行调用一个BAT文件,该文件可以在路径上提供各种工具。

第二个在目标二进制文件上运行EditBin,使用LARGEADDRESSAWARE 标志(这几乎是键盘上的所有左手键!)

同样取消选项:Project-> Properties-> Debug->启用Visual Studio宿主进程

 

这两行的唯一影响是调用EditBin在EXE中切换一点。当EXE启动一个进程时,整个进程被标记为能够使用2G以上的指针。

用这样的指针,高位是1,以2的补码表示,它是一个负数,有些应用程序可能没有被设计成与“负”指针一起工作。

 

现在,当我运行代码时,我获得了3.5 Gigs:超过两倍的内存!

 

#30 3,145,728,000

#31,350,585,600

#32 3,355,443,200

#33 3460,300,800

类型'System.OutOfMemoryException'的异常异常被抛出。

 

 

这个Editbin“技巧”在64位操作系统上运行良好。对于一个32位的操作系统来说,它也可以工作,但是你需要“bcdedit / set IncreaseUserVA 3072”(重新启动),你不会获得更多的额外内存。

 

想要更多的记忆?如果您使用的是64位操作系统,请尝试编译为64位:

VB:项目 - >属性 - >编译 - >高级 - >目标CPU - >任何CPU(或x64)

C#:Project-> Properies-> Build-> Platform Target->任何CPU(或x64)

 

#110 11,534,336,000

Iter#111 11,639,193,600

#112 11,744,051,200

#113 11,848,908,800

Iter#114 11,953,766,400

类型'System.OutOfMemoryException'的异常异常被抛出。

 

是的,这真的是我的8 gig机器上近12演出!  您也可以通过任务管理器进行验证。

 

一个64位进程有一个大小为64位(8字节)的指针。2 ^ 64 = 18,000,000,000,000,000,000。(1.8×10 ^ 19)

这大约有18艾字节,或90万年的DVD质量视频

 

不过这是隔靴搔痒的数量可能棋牌类游戏,甚至是waaaay较小的电子数量,将适合在宇宙Ĵ(哈勃定律,宇宙大爆炸物理学

 

当我第一次为微软工作时,我开发了一个thunking机制,允许32位应用程序调用16位DLL。(http://support.microsoft.com/kb/139070 

我们认为任何人都无法用完32位地址空间!

 

如果车牌号码的长度从6位增加到12位,这将从100万人(中等城市人口)增加到1Trillion(1×10 ^ 12),是世界人口的200倍。

 

 

也可以看看

BCDEdit命令行选项

有效地使用多个堆

你的计算机用所有的内存来做什么?编写你自己的内存浏览器

LARGEADDRESSAWARE

使用XAML创建您自己的测试主机来运行您的单元测试

未记录的API和16位DLL

 

<C#代码>

使用系统;

使用System.Collections.Generic;

使用System.Linq;

使用System.Text;

使用System.Windows;

使用System.Windows.Controls;

使用System.Windows.Data;

使用System.Windows.Documents;

使用System.Windows.Input;

使用System.Windows.Media;

使用System.Windows.Media.Imaging;

使用System.Windows.Navigation;

使用System.Windows.Shapes;

使用System.Runtime.InteropServices;

使用System.Diagnostics;

 

命名空间Heapcs

{

    /// <summary>

    /// MainWindow.xaml的交互逻辑

    /// </ summary>

    公共 部分  MainWindowWindow

    {

        public MainWindow()

        {

            的InitializeComponent();

        }

        private void Window_Loaded(object sender,RoutedEventArgs e)

        {

            VAR hHeap =  .HeapCreate(HeapFlags .HEAP_GENERATE_EXCEPTIONS,0,0);

            //如果FriendlyName是“heap.vshost.exe”,那么它使用VS托管进程而不是“Heap.Exe”

            Trace .WriteLine(AppDomain .CurrentDomain.FriendlyName + “heap created”);

            uint nSize = 100 * 1024 * 1024;

            ulong nTot = 0;

            尝试

            {

                forint i = 0; i <1000; i ++)

                {

                    var ptr = Heap .HeapAlloc(hHeap,0,nSize);

                    nTot + = nSize;

                    跟踪 .WriteLine(字符串 .Format(“Iter项目#{0} {1:N0}”,I,NTOT));

                }

            }

            catchException ex)

            {

                Trace .WriteLine(“Exception” + ex.Message);

            }

 

 

             .HeapDestroy(hHeap);

            Trace .WriteLine(“destroyed”);

            Application .Current.Shutdown();

        }

    }

 

    公共  

    {

        [ DllImport“kernel32.dll”,SetLastError = true)]

        public static extern IntPtr HeapCreate(HeapFlags flOptions,uint dwInitialsize,uint dwMaximumSize);

 

        [ DllImport“kernel32.dll”,SetLastError = true)]

        public static extern IntPtr HeapAlloc(IntPtr hHeap,HeapFlags dwFlags,uint dwSize);

 

        [ DllImport“kernel32.dll”,SetLastError = true)]

        public static extern bool HeapFree(IntPtr hHeap,HeapFlags dwFlags,IntPtr lpMem);

 

        [ DllImport“kernel32.dll”,SetLastError = true)]

        public static extern bool HeapDestroy(IntPtr hHeap);

 

        [ DllImport“kernel32.dll”,SetLastError = true)]

        public static extern IntPtr GetProcessHeap();

 

        [ 标志()]

        公共 枚举 HeapFlags

        {

            HEAP_NO_SERIALIZE = 0x1,

            HEAP_GENERATE_EXCEPTIONS = 0x4,

            HEAP_ZERO_MEMORY = 0x8

        }

 

    }

 

}

 

 

</ C#Code>

<VB代码>

选项严格打开

导入System.Runtime.InteropServices

 

 

MainWindow

    私人  Window_Loaded(BYVAL发件人作为系统。对象BYVAL Ë 作为 System.Windows。RoutedEventArgs把手 MyBase .Loaded

        暗淡 hHeap =  .HeapCreate(HeapFlags .HEAP_GENERATE_EXCEPTIONS,0,0)

        '如果FriendlyName是“heap.vshost.exe”,那么它使用VS Hosting进程而不是“Heap.Exe”

        Trace .WriteLine(AppDomain .CurrentDomain.FriendlyName + “创建的堆”

        Dim nSize As UInteger = 100 * 1024 * 1024

        Dim nTot As ULong = 0

        尝试

            对于 i = 1  1000

 

                Dim ptr = Heap .HeapAlloc(hHeap,0,nSize)

                nTot + = nSize

                跟踪 .WriteLine(字符串 .Format(“Iter项目#{0} {1:N0}”,I,NTOT))

            下一个

        抓住 EX 作为 例外

            Trace .WriteLine(“Exception” + ex.Message)

        结束 尝试

 

         .HeapDestroy(hHeap)

        Trace .WriteLine(“已销毁”

        结束

    结束 小组

 

公共

 

    < DllImport“kernel32.dll”,SetLastError:= True)> _

    公共 共享 函数 HeapCreate(

               BYVAL flOptions 作为 HeapFlags

               ByVal dwInitialSize 作为 UInteger

               ByVal dwMaximumSize 作为 UInteger

         )作为 IntPtr

    结束 功能

 

    < DllImport“kernel32.dll”,SetLastError:= True)>

    公共 共享 函数 HeapAlloc(

               ByVal hHeap 作为 IntPtr

               ByVal dwFlags As HeapFlags

               ByVal dwSize 作为 UInteger

         )作为 IntPtr

    结束 功能

    < DllImport“kernel32.dll”,SetLastError:= True)>

    公共 共享 函数 HeapFree(

               ByVal hHeap 作为 IntPtr

               ByVal dwFlags As HeapFlags

               ByVal lpMem As IntPtr

         )作为 布尔值

    结束 功能

 

    < DllImport“kernel32.dll”,SetLastError:= True)>

    公共 共享 函数 HeapDestroy(

               ByVal hHeap 作为 IntPtr

         )作为 布尔值

    结束 功能

 

    < DllImport“kernel32.dll”,SetLastError:= True)> _

    公共 共享 函数 GetProcessHeap(

         )作为 IntPtr

    结束 功能

    < 标志()>

    公共 枚举 堆标志

        HEAP_NO_SERIALIZE =&H1

        HEAP_GENERATE_EXCEPTIONS =&H4

        HEAP_ZERO_MEMORY =&H8

    End Enum

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值