.NET Out of Memory的问题

iTidy 2007-03-01 01:58:01
做一个比较大型的软件,经常会抛“Out of Memory”的异常。像2G内存的机器,一般到1.2G左右,甚至在900M+的时候就会抛出这个异常。

自己写了以下代码测试

int arrayCount = 5000;
int rang2ArrayCount = 1024* 100;
float[][] floatArray = new float[arrayCount][];
for (int i = 0; i < arrayCount; i++)
{
Console.WriteLine("=================={0}==================", i);
floatArray[i] = new float[rang2ArrayCount];


ShowMemory();
}

当每次申请4k空间时,Process的WorkingSet可以达到400+(512M内存的机器,下同),而每次申请4M空间的时候,只用到了27M内存就抛异常了。每次申请空间越小,则抛异常的内存上限就不同。请问各位大虾,这是怎么一回事?
...全文
776 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
iTidy 2007-03-01
  • 打赏
  • 举报
回复
fangbuge兄:您说的也有道理,至少在测试代码里,类型改成String后还没有出现问题,只是大量的占用了虚拟内存而已,没有异常。这样似乎可以得出一个结论,用float型可能是受到了系统堆栈大小的限制吧。有什么办法得出这个限制的大小吗?:)

用DataSet我不知道可不可行,而且改动比较大。用数组一开始的目的是顺序访问快,而且压缩存储到硬盘上方便。
planfore 2007-03-01
  • 打赏
  • 举报
回复
有800M空闲内存,并不是由800M连续的空闲内存。我只有在单次申请20M以上的内存时才可能会out of memory,
觉得,还是考虑有没有别的方法,以避免大量申请内存为好。
fangbuge 2007-03-01
  • 打赏
  • 举报
回复
你的程序是否可以改成使用DataSet,最好别这么玩。
fangbuge 2007-03-01
  • 打赏
  • 举报
回复
数组是需要连续存储的,所以一次分配一个大的空间肯定比小的更难找到吧!(我猜的)。


不防写把变量的类型改成STRING型的试试?
如果STRING型的效果会好的话,你完成可以改变一下程序吗!
(定义一个结构体,里面加上一个成员float[][] floatArray,不就可以了吗!)
iTidy 2007-03-01
  • 打赏
  • 举报
回复
回fangbuge兄:嗯,因为做的软件的数据也是简单的float型数据,主要用于仿真的,所以我才用float型的数据做测试,您说用string型我也试试。不过我说的问题是,为什么在测试代码里,每次数组规模小而数组个数多的情况下,抛出异常时的内存使用量比较大(400M),而在数组规模大的时候,抛异常时内存的使用量小(只有25M,27M左右)
iTidy 2007-03-01
  • 打赏
  • 举报
回复
hertcloud兄:可否再详细一点呢?
fangbuge 2007-03-01
  • 打赏
  • 举报
回复
你说以上的测试代码啊?
问你个问题?变量存在什么地方?简单变量存在什么地方?复合变量存在什么地方?
简单变量就是所说的INT型啦,BOOL型,它们是存在堆栈中的,当然系统的堆栈是有一定的限制的。
复合变量就是那类的变量,STRING型,结构体啦,它们是存在堆中的,当然系统的堆肯定要比堆栈大得多。

不防写把变量的类型改成STRING型的试试?
iTidy 2007-03-01
  • 打赏
  • 举报
回复
fangbuge兄:死循环应该不存在,因为在小数据量的时候,都可以完成运算的。而您看像我写的测试代码那么简单,也会出现这样的问题,这是为什么呢?
hertcloud 2007-03-01
  • 打赏
  • 举报
回复
这个应该是程序问题
可能是 你的 2维数组 造成的
iTidy 2007-03-01
  • 打赏
  • 举报
回复
刚单步了一下,每次申请4M,到25M的内存后再申请就一定抛异常,每次都很精确,我觉得这其中一定有什么限制我没发现。
fangbuge 2007-03-01
  • 打赏
  • 举报
回复
报Out of Memory异常,并非真正的内存不足(物理内存不够,也会使用虚拟内存的),是不是程序有死循环,或者函数反复调用?一般来说是程序编写的问题。
iTidy 2007-03-01
  • 打赏
  • 举报
回复
fangbuge兄:也许我没说清楚,我指的每次申请4K指的是new 一个1024大小的float数组。见测试代码
iTidy 2007-03-01
  • 打赏
  • 举报
回复
其实我是想知道这其中是怎么样一种机制,我好在代码里避免出现这样的异常。比如说之前有说。NET单进程最大允许物理内存的60%的说法,但我这个测试程序出现这样的问题表现说法似乎站不太住脚。
虽然内存数据可以缓冲到硬盘上,但这样很影响效率,对于小数据量情况下很不合算。所以要找到规律才能找到平衡点。
fangbuge 2007-03-01
  • 打赏
  • 举报
回复
“当每次申请4k空间时”?
LZ在做什么?为什么需要手工申请内存?
iTidy 2007-03-01
  • 打赏
  • 举报
回复
在软件里是有回收的,但软件的确需要很多内存,我们做了一个结果缓存在硬盘上,但那样很慢。关键是2G的内存还有800M空闲,怎么就会抛出Out of Memory的异常呢?

如果用测试代码,只申请少量的空间,都没问题,就是申请大量空间出现问题,但还有200M内存空闲的情况下只用了27M就报Out of Memory实在过不去吧
Red_angelX 2007-03-01
  • 打赏
  • 举报
回复
干嘛这么和机器过不去...
一般到1.2G左右...
又不是游戏一个程序占1G的内存还不吓死人
灰太狼 2007-03-01
  • 打赏
  • 举报
回复
不知道,你是否回收了?用GC强行回收试试。
如果可能的话,单步调一下,看看是哪出了问题。不一定就是你的代码测试的问题。
北京的雾霾天 2007-03-01
  • 打赏
  • 举报
回复
不明白,想做什么...

110,579

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧