请教C# Dictionary存储千万数据内存溢出问题

q511579599 2012-02-11 09:53:10
Dictionary正常情况下只能存储100w左右的数据,现在需要存上千万数据在Dictionary中,选择这种方式,是因为查找方便,耗时少。

我们采用的是两级Dictionary的方法,一级显然不够,将上千万数据分配到100个Dictionary中,每个Dictionary中,又存了3w多个Dictionary,但是每次程序运行到700多w的时候,内存就会溢出。

分配到100个Dictionary,我们用的是简单的GetHashCode(),请教大家,这个问题要怎么解决。谢谢啦。

PS:硬件方面条件充足,每次内存使用率不到50%,还有更大内存的机器可以使用,但是同样会内存溢出。
...全文
2056 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
谢谢。同样遇到这样的问题
q511579599 2012-02-14
  • 打赏
  • 举报
回复
目前问题算是解决了,和大家分享一下:

首先,创建一个固定大小的Directory,免得Directory扩容的时候浪费内存

然后,将程序编译成64位,PlatTarget 选X64,提高进城可用内存大小

最后,优化程序其他部分。

这样加载1900w数据到内存中,在内存只有8G的情况下,只用了9分钟,达到了老板的要求。
谢谢大家了。
nonocast 2012-02-13
  • 打赏
  • 举报
回复
或者考虑一下memcache
nonocast 2012-02-13
  • 打赏
  • 举报
回复
sqlite是正解
qldsrx 2012-02-13
  • 打赏
  • 举报
回复
先检测下程序本身可以申请到多少大小的内存,你可以申请一个实际物理内存80%大小的byte[],看看能否成功。
在上面成功的前提下,测试Dictionary的容量分配,将动态扩容改为静态设置,它有个capacity参数的重载。

如果问题还未解决,在实际内存可申请到的前提下,自己定义一个轻量级的Dictionary,反编译微软Dictionary的类并查看,实现Hash算法即可。
q511579599 2012-02-13
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 cuthkid 的回复:]

这么大的数据,还是放在数据库中吧,然后用条件过滤,上千W的数据一下子也看不完~~~
[/Quote]

本来是放数据库中的,但是读写数据库很耗时,才要放内存中,现在是内存不缺,就想提高性能,缩短程序执行时间。
谢谢你的答复。
dean615 2012-02-13
  • 打赏
  • 举报
回复
这么大的数据,还是放在数据库中吧,然后用条件过滤,上千W的数据一下子也看不完~~~
烟波钓 2012-02-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 q511579599 的回复:]
引用 7 楼 yanbuodiao 的回复:

引用 4 楼 q511579599 的回复:
引用 1 楼 wodegege10 的回复:

这个跟Dictionary关系不大,应该使用64位系统、

将程序编译成64位


现在我们用的确实是64位机,程序里没有x64,只有x86,我们选的是any cpu

数据量这么大的话 同时使用么?
对于一些使用少的 存起来的给压……
[/Quote]
1.加载数据的时候仅仅加载需要使用的
2.或者像qldsrx说的那样定义自己轻量级的Directory

如果还是不能解决 找老板 找客户 提高机器配置 嘿嘿
ViewStates 2012-02-11
  • 打赏
  • 举报
回复
32位应用程序最大能使用内存为2G。
我觉得你在这块不应该使用这种方式来解决问题,你应该额外搞个缓存服务器做这个。
q511579599 2012-02-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 yanbuodiao 的回复:]

引用 4 楼 q511579599 的回复:
引用 1 楼 wodegege10 的回复:

这个跟Dictionary关系不大,应该使用64位系统、

将程序编译成64位


现在我们用的确实是64位机,程序里没有x64,只有x86,我们选的是any cpu

数据量这么大的话 同时使用么?
对于一些使用少的 存起来的给压缩一下吧 完后使用的时候 在给解压缩了 以前……
[/Quote]

首先谢谢你的回答

现在的需求确实是要全部使用的,这些数据本来是以文件形式存在磁盘上的,我们碰到的问题是,把这些数据从文件中load到内存中时,发生内存溢出的。
烟波钓 2012-02-11
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 q511579599 的回复:]
引用 1 楼 wodegege10 的回复:

这个跟Dictionary关系不大,应该使用64位系统、

将程序编译成64位


现在我们用的确实是64位机,程序里没有x64,只有x86,我们选的是any cpu
[/Quote]
数据量这么大的话 同时使用么?
对于一些使用少的 存起来的给压缩一下吧 完后使用的时候 在给解压缩了 以前做的 压缩后 数据量是未压缩前的1/5大小
q511579599 2012-02-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 jarun 的回复:]

这样的需求难道不能换一种方式实现?
[/Quote]

我们还用了另一种方式Sqlite来存储这些数据,需要的时候,用sql语句去查询,但是这种方式太耗时,才想用这种方法把数据全都加载到内存中,Dictionary查找也方便
q511579599 2012-02-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 vkv123 的回复:]

1、编译成64位系统
2、你要让程序在运行中有动作,不然还会停止的,比如显示个时间都可以,或是加个序号,让它不断加,反正就是不能只执行这一个动作,不然会出现停止错误
[/Quote]

我们在后台用log记录,能看到序号的增加
q511579599 2012-02-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wodegege10 的回复:]

这个跟Dictionary关系不大,应该使用64位系统、

将程序编译成64位
[/Quote]

现在我们用的确实是64位机,程序里没有x64,只有x86,我们选的是any cpu
  • 打赏
  • 举报
回复
这样的需求难道不能换一种方式实现?
vkv123 2012-02-11
  • 打赏
  • 举报
回复
1、编译成64位系统
2、你要让程序在运行中有动作,不然还会停止的,比如显示个时间都可以,或是加个序号,让它不断加,反正就是不能只执行这一个动作,不然会出现停止错误
wenbin 2012-02-11
  • 打赏
  • 举报
回复
这个跟Dictionary关系不大,应该使用64位系统、

将程序编译成64位

110,538

社区成员

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

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

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