首页 新闻 会员 周边 捐助

在生成缩略图时,跑到大概2000多张图片时(全景图片,大小4.5M左右),会出现内存不足提示,然后崩掉。请问这个地方有问题吗?

0
[已解决问题] 解决于 2017-07-13 15:34

//获取jpg
string[] pFilePath = Directory.GetFiles(rawPath, "*.jpg");
if (pFilePath.Length == 0)
{
XtraMessageBox.Show("未从原路径中找到 jpg 图片", "提示", MessageBoxButtons.OK);
return pFilePath;
}

//生成缩略图
for (int i = 0; i < pFilePath.Length; i++)
{
FileStream pFs = new FileStream(pFilePath[i], FileMode.Open, FileAccess.Read);
string pName = System.IO.Path.GetFileName(pFilePath[i]);

System.Drawing.Image pImage = System.Drawing.Image.FromStream(pFs);
double width = pImage.Width;
double height = pImage.Height;
double pCurrRatio = width / height;

int pWidth = 750;
int pHeight = (int)Math.Round(pWidth / pCurrRatio);
string pSmallImage = string.Format("{0}\\1_{1}", newPath, pName);
MakeThumbnail(pFilePath[i], pSmallImage, pWidth, pHeight, "hw");

pImage.Dispose();
pFs.Close();
}

问题补充:

改成这个样子呢?

//生成缩略图
for (int i = 0; i < pFilePath.Length; i++)
{
using (FileStream pFs = new FileStream(pFilePath[i], FileMode.Open, FileAccess.Read))
{
string pName = System.IO.Path.GetFileName(pFilePath[i]);

System.Drawing.Image pImage = System.Drawing.Image.FromStream(pFs);
double width = pImage.Width;
double height = pImage.Height;
double pCurrRatio = width / height;
int pWidth = 750;
int pHeight = (int)Math.Round(pWidth / pCurrRatio);
string pSmallImage = string.Format("{0}\\1_{1}", newPath, pName);
MakeThumbnail(pFilePath[i], pSmallImage, pWidth, pHeight, "hw");

pImage.Dispose();
GC.Collect();
Application.DoEvents();
}
}

一叶知秋somthing的主页 一叶知秋somthing | 菜鸟二级 | 园豆:208
提问于:2017-07-12 08:35
< >
分享
最佳答案
1

所以你是要测试啥时候能耗光你的内存并崩掉吗?你这么写,GC哪儿有空去清理内存?

代码里面给个喘息的机会给系统吧。

奖励园豆:5
爱编程的大叔 | 高人七级 |园豆:30844 | 2017-07-12 09:53

就是说要在循环里,加一条GC。Collect()吗?

一叶知秋somthing | 园豆:208 (菜鸟二级) | 2017-07-12 09:56

@一叶知秋somthing: 

https://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents(v=vs.110).aspx

循环里面加个Doevents或者你把单个文件处理交给单个线程。系统自然会管理好线程。

你现在这样,磁盘IO和CPU全部都被你占用了。

爱编程的大叔 | 园豆:30844 (高人七级) | 2017-07-12 10:00

@爱编程的大叔: 谢谢大叔啊,不是很明白,正在努力学习中。非常感谢

一叶知秋somthing | 园豆:208 (菜鸟二级) | 2017-07-12 10:21

@爱编程的大叔: 我将代码加了DoEvents,用using后,还是会出现这个问题,完了我又尝试将目标平台*86改成了*64,在处理的按钮里写了

Process pProcess = Process.GetCurrentProcess();
pProcess.MaxWorkingSet = Process.GetCurrentProcess().MaxWorkingSet;

跑几次到6000张左右暂时没出内存不足的问题。

求教,能简单讲一下吗,不是很明白

一叶知秋somthing | 园豆:208 (菜鸟二级) | 2017-07-13 10:19
其他回答(4)
1

加个 pFs.Dispose();

再使用System.GC.Collect()来强制进行GC,用System.GC.WaitForFullGCComplete()等待GC完成。

hahanonym | 园豆:1460 (小虾三级) | 2017-07-12 09:06

感谢啊,我刚又光测了一下这个方法,跑了4000张图片没出问题,而且我一直看着资源管理器,内存稳定,不知道上次那是怎么回事,我看看加上强制回收,和用3楼的using再实测一下

支持(0) 反对(0) 一叶知秋somthing | 园豆:208 (菜鸟二级) | 2017-07-12 09:33
0

MakeThumbnail你这个方法怎么写的?有释放吗?

ChixTech | 园豆:171 (初学一级) | 2017-07-12 09:06

这个方法应该没问题,用过很多次了,而且所有的都释放了,也强制回收了,

支持(0) 反对(0) 一叶知秋somthing | 园豆:208 (菜鸟二级) | 2017-07-12 09:34
1

using(FileStream pFs = new FileStream(pFilePath[i], FileMode.Open, FileAccess.Read))

{xxx}

猝不及防 | 园豆:2878 (老鸟四级) | 2017-07-12 09:20

这个好,我再改下测试测试

支持(0) 反对(0) 一叶知秋somthing | 园豆:208 (菜鸟二级) | 2017-07-12 09:35

@一叶知秋somthing: 第一次被人赞,好开心~

支持(0) 反对(0) 猝不及防 | 园豆:2878 (老鸟四级) | 2017-07-12 10:59

@猝不及防: 猝不及防啊 0.0

支持(0) 反对(0) 一叶知秋somthing | 园豆:208 (菜鸟二级) | 2017-07-12 11:00
0

这种stream 非托管资源,需要去手动释放资源,CLR不会对你这个非托管资源负责

论值类型与引用类型的内存分配情况

托管资源与非托管资源的区别

~扎克伯格 | 园豆:1923 (小虾三级) | 2017-07-12 10:59

我释放stream了

支持(0) 反对(0) 一叶知秋somthing | 园豆:208 (菜鸟二级) | 2017-07-13 10:20
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册