频繁new大内存后delete动作,导致out of memory?如何解决呢?

kingovern 2011-04-01 10:07:06
我在一个函数中读取百兆以上大文件数据,用new开销,进行数据操作后delete。但是当我频繁调用该函数时,产生内存溢出。该如何解决呢?
...全文
444 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
stain_less 2011-04-02
  • 打赏
  • 举报
回复
只能用单态设计模式来解决
辰岡墨竹 2011-04-01
  • 打赏
  • 举报
回复
多余大于5MB以上的内存分配不要使用new,因为new是对malloc的封装,而malloc封装了HeapAlloc。Windows的堆默认大小为1MB,虽然会自动增长,但是他本身的分配算法是适合较小的零碎数据。而且HeapAlloc又是靠VirtualAlloc分配内存页的,所以频繁调用效率会低好多倍。
对于大文件应该先用VirtualAlloc分配一块大的内存区域,然后用MapFile映射文件,因为有磁盘缓冲区的,所以只要你的读写是比较有序的话,性能是很高的。不过如果你不要求文件的实时更新的话,可以直接把文件读入到VirtualAlloc分配的区域里,修改设计,取消不必要的读写。
snake_xiongyang 2011-04-01
  • 打赏
  • 举报
回复
LS说的就是单一实例设计模式 楼主你的情况确实很适合这种情况
而且就算是你正确地删除了实例,因为new delete的缘故 依然性能低。
如果可以确保只有有限个实例,可以使用这个模式
stain_less 2011-04-01
  • 打赏
  • 举报
回复
频繁使用new,产生多个对象实例,即使删除了数据,实例对象依旧逐流内存成为垃圾,垃圾没有及时回收导致内存溢出。
建议不要“用new开销”,调用这个函数时不要用new创建对象,而在需要对象实例的类中用静态方法提前new一个实例,外部需要这个类的实例的时候,不再new,而是都调用这个静态方法,并提供这个静态方法new的那个实例,这样,即使多次调用函数,内存中只有一个对象实例,不会出现内存溢出。
iambic 2011-04-01
  • 打赏
  • 举报
回复
不要频繁申请释放,使用内存池之类的重用内存。
pathuang68 2011-04-01
  • 打赏
  • 举报
回复
1. 考虑使用内存映射,即用操作内存的方式,操作硬盘,性能肯定会有所下降;
2. 重构你的设计。既然一次性把几百兆的文件,读入内存,这种new或者delete就不应该太过频繁。

顺便问一下,大概多长时间就要进行一次new/delete操作?
kingovern 2011-04-01
  • 打赏
  • 举报
回复
是的,LoadFromFile,一次性读入。
showjim 2011-04-01
  • 打赏
  • 举报
回复
汗,难道每次都把整个文件读到内存?
luciferisnotsatan 2011-04-01
  • 打赏
  • 举报
回复
内存映射

另外,你也不用把百兆的一起加到内存里吧。
bdmh 2011-04-01
  • 打赏
  • 举报
回复
看你怎么弄得了,怎么打开的文件,对于大文件,建议用内存映射
c_losed 2011-04-01
  • 打赏
  • 举报
回复
44 内存映射
cxyOOOO 2011-04-01
  • 打赏
  • 举报
回复
物理内存多少,怎样频繁,最好能调试一下查原因,2G的进程空间消耗光,还不带回收的(假设进程只开单个文件缓冲的情况感觉比较奇怪哈,多开倒是可能)。
赵4老师 2011-04-01
  • 打赏
  • 举报
回复
读写超过2GB的文件用_lseeki64函数
赵4老师 2011-04-01
  • 打赏
  • 举报
回复
内存碎片
quwei197874 2011-04-01
  • 打赏
  • 举报
回复
用内存池.
ameyume 2011-04-01
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 luciferisnotsatan 的回复:]
还是应该把数据拆开来。
如果你是32位系统,那么你能用的也就2G(非3G用户态内存情况下)不到。而你要new个百兆的连续地址,那是比较困难的。比如你要new个 500M的,即使还有1G多的空间,但也不一定有连续500M的给你用
[/Quote]
就是,new的内存都是连续分配的,哪有那么多内存供你频繁操作。即使new完立刻delete,这时候也不一定就立刻释放了。
luciferisnotsatan 2011-04-01
  • 打赏
  • 举报
回复
还是应该把数据拆开来。
如果你是32位系统,那么你能用的也就2G(非3G用户态内存情况下)不到。而你要new个百兆的连续地址,那是比较困难的。比如你要new个 500M的,即使还有1G多的空间,但也不一定有连续500M的给你用
太乙 2011-04-01
  • 打赏
  • 举报
回复
加内存!
苍蝇①号 2011-04-01
  • 打赏
  • 举报
回复
可以设置内存池 循环使用 减少new delete的频次

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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