c#数组的内存分配
来源:互联网 发布:代谢综合征临床数据库 编辑:程序博客网 时间:2024/05/21 09:43
引起我对这个题目的兴趣的原因是这样的,有客户抱怨公司的产品运行时out of memory了,于是我便开始研究这个问题到底出在什么地方。
当时程序的运行状态是这样的,一共有10000个数组(请尽情吐槽程序的结构设计),第一个数组中有6个object,第二个数组有12个object,以此类推,第10000个数组有60000个object。整个程序中该object的数量只有60000个,也就是说第一个数组中的6个object就是最后一个数组的前六个object。
当调试到这里,我立刻想到,难道是60000个object导致了OOM?
于是使用了dotTrace发现这6W个object只占了几百M的内存,而OOM异常起码内存占用要超过2G。
到底是什么东西占用了这么大的内存?
想着这个问题时,突然眼睛瞟到dotTrace内存报告中显示object[]占用了极大的内存,超过了那6w个object。至此,总算找到了OOM的原因:大量的数组占用了大量的内存。与此同时,另外一个问题又出现了。
数组为何会占用如此大量的内存?object数组存储的应该仅仅只是object的地址,地址怎么会占用这么大的内存?对于这个问题,我百思不得其解。
一开始,我以为是ArrayList的内存开辟,因为ArrayList可以动态更改数组长度,也就会动态的开辟内存,而每次内存开辟是在上一次的数组长度上乘2,于是我使用了TrimToSize()方法来削减多余开辟的内存,问题仍然没有解决。
不甘心的我直接将ArrayList改成object[],当然,大家应该可以预见,问题仍不会得到解决。
无计可施的我最后只能求助于google,数组的内存分配到底是怎样的。于是查到了这样一篇文章:
http://stackoverflow.com/questions/487202/memory-layout-of-a-net-array
在回复里面,有人详细解答了数组的内存分配。
大致是这样说的:
对于一个32位的程序
- 数组的前4个byte保存method table地址.
- 接下来4个byte保存数组长度.
- 再下来就是数组的元素,每个对象的地址,需要4个bytes.
- 最后4个byte为空。不是非常确定,但是猜测是用来保存syncblock数组的引用当实例被lock住的时候
这样一来,我根据这个信息简单计算了一下程序里面大量数组所占用的内存:
10000个数组,总共占用了N个bytes来保存对象的地址
N=(6+12+18+……+60000)*4=1200120000
N约为1个G
到了这里我才恍然大悟,别小看对象的地址这小小的4个byte,在糟糕的程序结构设计,变态用户的需求等条件下,一切皆有可能。
- c#数组的内存分配
- C#数组变量的内存分配
- 数组的内存分配图
- 数组的动态内存分配
- 数组的动态内存分配
- 二维数组的内存分配
- 数组越界的内存分配
- C# List的内存分配
- 二维数组的内存分配及删除
- 指针数组的malloc分配内存例子
- 数组和JVM的内存分配
- 二维数组的动态内存分配
- java数组的初始化与内存分配
- 二维数组的动态内存分配
- Java基础-数组的内存分配
- 指针与数组的内存分配
- Java多维数组的内存分配
- java数组的定义和内存分配
- iphone开发中的各种动画效果
- char* p="abc"与char p[] = "abc"区别
- #pragma warning指令
- bitblt()用法
- 如何使log文件达到指定大小就转储(logrotate)
- c#数组的内存分配
- 解决ReportViewer的双竖滚动条的问题
- Session丢失问题调试
- 时钟使用使用
- (源码)jsp案例(简单的一个web四则运算)
- [收藏] 最受欢迎的ASP.NET的CMS下载
- 关于播放器JPlayer的使用及遇到的问题
- mysql数据库编程精华案例347个(知此347个例子,便是高手矣)
- __bridge,__bridge_retained和__bridge_transfer的意思,区别与使用