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

2023-11-29 03:32

本文主要是介绍内存不足?简单的方法来增加程序的可用内存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转自 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

这篇关于内存不足?简单的方法来增加程序的可用内存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/431290

相关文章

Python清空Word段落样式的三种方法

《Python清空Word段落样式的三种方法》:本文主要介绍如何用python-docx库清空Word段落样式,提供三种方法:设置为Normal样式、清除直接格式、创建新Normal样式,注意需重... 目录方法一:直接设置段落样式为"Normal"方法二:清除所有直接格式设置方法三:创建新的Normal样

在Linux系统上连接GitHub的方法步骤(适用2025年)

《在Linux系统上连接GitHub的方法步骤(适用2025年)》在2025年,使用Linux系统连接GitHub的推荐方式是通过SSH(SecureShell)协议进行身份验证,这种方式不仅安全,还... 目录步骤一:检查并安装 Git步骤二:生成 SSH 密钥步骤三:将 SSH 公钥添加到 github

把Python列表中的元素移动到开头的三种方法

《把Python列表中的元素移动到开头的三种方法》在Python编程中,我们经常需要对列表(list)进行操作,有时,我们希望将列表中的某个元素移动到最前面,使其成为第一项,本文给大家介绍了把Pyth... 目录一、查找删除插入法1. 找到元素的索引2. 移除元素3. 插入到列表开头二、使用列表切片(Lis

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

Java中使用 @Builder 注解的简单示例

《Java中使用@Builder注解的简单示例》@Builder简化构建但存在复杂性,需配合其他注解,导致可变性、抽象类型处理难题,链式编程非最佳实践,适合长期对象,避免与@Data混用,改用@G... 目录一、案例二、不足之处大多数同学使用 @Builder 无非就是为了链式编程,然而 @Builder

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分