关于new Bitmap,不是只有一个img吗?为什么不进行Dispose()内存就会不断增加直至"虚拟内存不足"而崩掉?

andyqq8 2011-05-25 05:30:38
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace getpm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}


private void button1_Click(object sender, EventArgs e)
{
Image img = null;
for (int i = 0; i < 100; i++)
{
img = new Bitmap(1440, 900);
//img.Dispose(); //Diepose了就是正常设想的不加内存的。。。
}

}
}
}



别笑,我确实基础不好。。。按我的理解,只建了一个img,后面100次new Bitmap应该类似于ie的"f5"键刷新而已呀,可是这个怎么像是img[0->99]的数组一样实例了100次呢,button1_Click一次增加约500M内存,2g的内存button1_Click三次这个测试程序就崩了。。。那假如我想img只刷新,不Dispose也不会增加内存该如何实现呢?下面这样四百八十万次都一点内存都没有增加,这又是为何,难道rgb不需要内存保存的吗?
          for (int i = 0; i < 4800000; i++)
{
Color rgb= img.GetPixel(100, 100);
}
...全文
359 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
isjoe 2011-05-25
  • 打赏
  • 举报
回复

//你这一行代码每次就产生约4.94MB内存。。。。。
img = new Bitmap(1440, 900);




for (int i = 0; i < 4800000; i++)
{
Color rgb= img.GetPixel(100, 100);
}
// 你上面这个循环和下面的没什么区别。。。
for (int i = 0; i < 4800000; i++)
{
int n = 0;
}




kid_wang 2011-05-25
  • 打赏
  • 举报
回复
“只建了一个img,后面100次new Bitmap应该类似于ie的"f5"键刷新而已呀”——
大哥,您这个理解想当然了
andyqq8 2011-05-25
  • 打赏
  • 举报
回复
虽然还是一知半解,但大概料懂原理了,谢谢两位,工作happy!
ghost5216 2011-05-25
  • 打赏
  • 举报
回复
for (int i = 0; i < 4800000; i++)
{
Color rgb= img.GetPixel(100, 100);
}
因为Color是值类型,每次执行一次都进栈出栈释放很快,内存自然不受影响。
Bitmap是引用类型,由GC回收。
ghost5216 2011-05-25
  • 打赏
  • 举报
回复

private void button1_Click(object sender, EventArgs e)
{
Image img = null;
for (int i = 0; i < 100; i++)
{
img = new Bitmap(1440, 900);
//img.Dispose(); //Diepose了就是正常设想的不加内存的。。。
}

}

使用完 Image 后调用 Dispose。 Dispose 方法使 Image 处于不可用状态。 调用完 Dispose 后,必须释放对 Image 的所有引用,这样垃圾回收器才能收回 Image 占用的内存。

只声明了一个Image img
当第一次执行img = new Bitmap(1440, 900);时
这个img是能找到对象的。
当第二次执行img = new Bitmap(1440, 900);时
第一次new的Bitmap变找不到了,因为它的引用(可以想象成指针)被覆盖了,只想了新的BitMap
也就说你在循环是只有最后一次img = new Bitmap(1440, 900);的对象是有效的,能引用到的。
在此之前的都引用不到了,CLR会检查它们的引用计数,如果没有线程引用它们了,就做标记,在GC垃圾回收时,回收内存。
可是垃圾回收不是实时运行的。在你new Bitmap新的对象时,垃圾回收可能还没运行,标记回收的对象还在内存中,如果内存不够用,CLR会把一些不经常引用的对象置换到虚拟内存,腾出内存供最新对象使用。你不断的置换页面,很快填满了虚拟内存。

我认为即使不Dispose的话,内存最后也会释放,只是时间要久一些。
Dispose是好习惯。


111,092

社区成员

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

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

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