c#程序内存分配

c#程序内存分配

进程可使用内存数就是操作系统给进程分配的最大地址,一般的32位操作系统提供给用户地址最大都是3g(操作系统自己保留1g),windows由于商业目的,对于个人用户只提供了2g地址,要使用3g扩展需要对系统配置作修改。还有就是intel的32位芯片实际上是支持36位寻址能力的(64g),但是也是出于商业目的对于大部分个人芯片都禁止了这个功能,这个禁止可能是物理上的限制个人用户几乎无法修改。

而且在操作系统中物理可用内存和进程实际占用内存是有区别的,因为有虚拟地址和交换区这种概念,进程实际使用的内存量远远大于物理可用内存,最简单的一个例子就是声明一个非常大的数组但不存放任何东西,进程启动后占用的物理内存可能很小但是申请的内存地址却是非常大了(虚拟内存数),所以就可能产生这么一种情况:空闲物理内存很多进程所占物理内存很小但却报了内存不够,因为进程可用地址已经完全被分配完了(申请很多,却没有用。所以要JIT,lazy...)。

有些时候由于代码的问题(确切地说是不了解framework的内存使用机制)也会导致outofmemory,一般占用大内存的情况就是list和hashtable2种结构,而这2种数据结构实际上都是使用数组作为容器存放元素的,由于数组是定长结构所以当达到上限时需要做动态扩容,动态扩容的算法都是2倍当前数组长度,数组本身又是需要连续内存作为保证,如果内存碎片过多就会导致没有连续内存可用,.net的智能垃圾回收器也没办法完全避免内存碎片(可以通过禁止垃圾回收或者降低垃圾回收频率来避免碎片,但是需要手工回收来解决内存增长问题),所以在使用list或者hashtable的时候最好能事先指定需要的最大容量上限,避免到后面因为碎片问题导致outofmemory。比如申请的初始内存块不够大,后期要分配更大内存,在本块内存区后面没有这么大的连续空闲内存,就会outofmemory。

小计:C# List的内存分配

当List<T>对象的Item元素数量超过了Capacity的数量时,List<T>对象会重新申请一块大小是原来Capacity的两倍的内存空间,然后将当前所有Item元素以及待添加元素复制到新的内存空间中。

知道了内存分配的原则,接下来就得根据这些原则来采用最优的方法保证有限的内存空间能得到合理的运用。归纳起来主要有如下你点:
1.当实例化一个List<T>对象时,如果能预知其Item元素的大致个数,应该在实例化一个List<T>对象的时候设置其Capacity值为接近于Item元素个数的最小值。这样的话可以避免在像List<T>中添加元素的时候,不断的申请内存与元素的复制。

2.当由于不断的调用Remove方法而导致Item元素的个数远远小于Capacity,就会造成内存的浪费。此时可以调用TrimExcess方法释放多余的内存。

c# 线程池 http://wenku.baidu.com/view/a6f14375f46527d3240ce01b.html

=====================================

Chat Question: Memory Limits for 32-bit and 64-bit processes

During our recent blog chat, there were a number of topics that were asked about and I am going to expand on some of them.  The first one is the memory limits for different processes.

This really depends on a few different things.  The architecture of the process (32-bit or 64-bit) and also the architecture of the Operating System the process is running on.  For 32-bit it also depends if you use the /3GB switch or not.

So I broke this up based on these things into the table below, this is the maximum amount of memory available for the process assuming you have that much RAM and Pagefile space.


32-bit OS


64-bit OS


32-bit process


2 GB


4 GB


32-bit process with /3GB


3 GB


N/A


64-bit process


N/A


16 TB

These process numbers are contingent on how much RAM and disk space you have, so if you have 4 GB of RAM(内存) and 4 GB Pagefile(虚拟内存), the total memory of all running processes can’t be greater then 8 GB.

Note: If you let Windows manage your Pagefile size, when you hit this limit, Windows will try to grow your Pagefile as long as there is disk space available.

For the amount a .NET application will use before we can expect to see out of memory, those numbers are:


32-bit OS


64-bit OS


32-bit process


800-1200 MB


2800 MB


32-bit process with /3GB


1800 MB


N/A


64-bit process


N/A


2800 MB if using a 4 GB process or more if more RAM (around 70% of RAM + Pagefile)

Keep in mind that although a .NET process can grow this large, if the process is multiple GB in size, it can become very difficult for the Garage Collector to keep up with the memory as Generation 2 will become very large.  I’ll talk about the generations more in an upcoming post.

Hopefully that will clear up how much memory each one uses.

Keep checking the RECAP- ASP.NET Blog Chat to see other topics that Tess or I write about.

当前标签: C#

c#实现golang 的channel visionwang 2013-12-03 21:18 阅读:398 评论:0

.NET中的GC总结 visionwang 2013-10-15 21:54 阅读:165 评论:0

linq中不能准确按拼音排序 visionwang 2013-10-14 16:37 阅读:42 评论:0

c#程序内存分配 visionwang 2013-04-24 23:08 阅读:3126 评论:0

.net平台下连接池概述 visionwang 2012-11-16 23:34 阅读:187 评论:0

时间: 2024-08-29 08:10:21

c#程序内存分配的相关文章

C/C++程序内存分配(和Linux进程分配有一些区别)

C/C++程序内存分配 一.一个由C/C++编译到程序占用的内存分为以下几个部分: 1.栈区(stack)--由编译器自动分配释放,在不需要的时候自动清除.用于存放函数的参数.局部变量等.操作方式类似数据结构中的栈(后进先出). 2.堆区(heap)--一般由程序员分配释放,若程序员分配后不释放,程序结束后可能由OS回收.不同于数据结构中的堆,分配方式有些类似链表. 3.全局区(静态区)--全局变量和静态变量存储在这里.程序结束后由系统释放.在以前到C语言中,全局变量又细分为初始化的(DATA段

c语言程序内存分配

转自: http://book.51cto.com/art/200811/96138.htm C语言编译后的可执行程序的存储结构和运行结构 可执行程序在存储时(没有调入到内存)分为代码区(text).数据区(data)和未初始化数据区(bss)3个部分. (1)代码区(text segment).存放CPU执行的机器指令(machine instructions).通常,代码区是可共享的(即另外的执行程序可以调用它),因为对于频繁被执行的程序,只需要在内存中有一份代码即可.代码区通常是只读的,使

C程序内存分配

在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中.这个沙盘就是虚拟地址空间(virtual address space),在32位模式下它总是一个4GB的内存地址块.这些虚拟地址通过页表(page table)映射到物理内存,页表由操作系统维护并被处理器引用.每一个进程拥有一套属于它自己的页表,但是还有一个隐情.只要虚拟地址被使能,那么它就会作用于这台机器上运行的所有软件,包括内核本身.因此一部分虚拟地址必须保留给内核使用: 这并不意味着内核使用了那么多的物理内存,仅表示它可支配

C/C++程序内存分配详解

一.常见的几个区 1.栈区(stack)程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放. 2.堆区(heap)在内存开辟另一块存储区域.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表. 3.全局区(静态区)(static) 编译器编译时即分配内存.全局变量和静态变量的存储是放在一块的,初始化的 全局变量和静态变量在一块区域, 未初始化的全局变量和未

C++程序内存分配方式(堆与栈)

一.内存布局 1.栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量值等,其操作方法类似数据结构中的栈. 2.堆区(heap):一般由程序员分配释放,与数据结构中的堆毫无关系,分配方式类似于链表. 3.全局/静态区(static):全局变量和静态变量的存储是放在一起的,在程序编译时分配. 4.文字常量区:存放常量字符串. 5.程序代码区:存放函数体(类的成员函数.全局函数)的二进制代码 二.栈与堆的比较 1.申请方式 stack:系统自动分配,如声明int a;系统自动在栈空间

程序内存分配

____________________ | Stack区(栈区)(函数参数,局部变量,数组):自动创建,函数结束时自动释放,速度快,容量小 |____________________ | Static存储区(static变量,全局变量): 程序编译的时候就分配好 |____________________ |                                                     : 通过malloc/new等资源申请函数分配,需要程序员主动释放 | Heep区

C/C++——程序的内存分配

C/C++程序内存分配 一.预备知识-程序的内存分配 一个由c/C++编译的程序占用的内存分为下面几个部分 1.栈区(stack):由编译器自己主动分配释放 ,存放函数的參数值,局部变量的值等.其操作方式相似于数据结构中的栈. 2.堆区(heap): 一般由程序猿分配释放, 若程序猿不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事.分配方式倒是相似于链表,呵呵. 3.全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,

内存分配方式及内存碎片

什么是内存碎片? 内部碎片的产生:因为所有的内存分配必须起始于可被 4.8 或 16 整除(视 处理器体系结构而定)的地址或者因为MMU的分页机制的限制,决定内存分配算法仅能把预定大小的内存块分配给客户.假设当某个客户请求一个 43 字节的内存块时,因为没有适合大小的内存,所以它可能会获得 44字节.48字节等稍大一点的字节,因此由所需大小四舍五入而产生的多余空间就叫内部碎片.外部碎片的产生: 频繁的分配与回收物理页面会导致大量的.连续且小的页面块夹杂在已分配的页面中间,就会产生外部碎片.假 设

C语言中内存分配

C语言中内存分配 在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重点介绍C程序中内存的分配,以及C语言编译后的可执行程序的存储结构和运行结构,同时还介绍了堆空间和栈空间的用途及区别. 第2节主要介绍C语言中内存分配及释放函数.函数的功能,以及如何调用这些函数申请/释放内存空间及其注意事项. 3.1 内存管理基本概念 3.1.1 C程序内存分配 1