Редактировать: Добавлен код (Исключение в строке 095, 5-й раз, когда он нажал).
public DataTable ParseBarcodes(String[] files, BarcodeZoneScan[] scanParameters)
{
message = null;
//gmseBitmap img = null;
gmseBitmap rotImg = null;
gmseBitmap parseImage = null;
gmseBitmap tempImage = null;
DataTable codes = new DataTable();
codes.Columns.Add("PageNumber");
codes.Columns.Add("Text");
codes.Columns.Add("Type");
codes.Columns.Add("RegionName");
try
{
gmseBarcodeInfoCollection bcc;
gmseBarcodeReaderParameter param = new gmseBarcodeReaderParameter();
gmseLicense.License = "plaintext license key ommited";
String dvImageName;
int searchCount = 0;
for (int dvCount = 0; dvCount < files.Length; dvCount++)
{
if (cancelled) //If cancelled, end the loops
{
dvCount = files.Length;
break;
}
dvImageName = files[dvCount].ToString();
using (gmseBitmap img = new gmseBitmap(dvImageName))
{
int framecount = img.GetFrameCount();
for (int e = 0; e < framecount; e++)
{
for (int j = 0; j < scanParameters.Length; j++)
{
if (scanParameters[j].Range == PageRange.All ||//All
(scanParameters[j].Range == PageRange.Even && (searchCount == 0 || searchCount % 2 == 0)) || //even
(scanParameters[j].Range == PageRange.Odd && (searchCount != 0 && searchCount % 2 != 0)) ||
(scanParameters[j].Range == PageRange.First && searchCount == 0))
{
//Setup what barcodes are going to be search for
param.BarcodeType = 0;
if (scanParameters[j].BarcodeTypes == BarcodeType.All) //All
{
param.BarcodeType = (int)gmseBarcodeType.All;
}
else
{
if ((scanParameters[j].BarcodeTypes & BarcodeType.Code39) != 0) //Code 39
param.BarcodeType = param.BarcodeType | (int)gmseBarcodeType.Code39;
if ((scanParameters[j].BarcodeTypes & BarcodeType.Code11) != 0) //Code 11
param.BarcodeType = param.BarcodeType | (int)gmseBarcodeType.Code11;
if ((scanParameters[j].BarcodeTypes & BarcodeType.Code93) != 0) //Code 93
param.BarcodeType = param.BarcodeType | (int)gmseBarcodeType.Code93;
if ((scanParameters[j].BarcodeTypes & BarcodeType.Code128) != 0) //Code 128
param.BarcodeType = param.BarcodeType | (int)gmseBarcodeType.Code128;
if ((scanParameters[j].BarcodeTypes & BarcodeType.Ean8) != 0) //EAN 8
param.BarcodeType = param.BarcodeType | (int)gmseBarcodeType.EAN8;
if ((scanParameters[j].BarcodeTypes & BarcodeType.Ean13) != 0) // EAN 13
param.BarcodeType = param.BarcodeType | (int)gmseBarcodeType.EAN13;
if ((scanParameters[j].BarcodeTypes & BarcodeType.I2of5) != 0) //I2of5
param.BarcodeType = param.BarcodeType | (int)gmseBarcodeType.i2of5;
}
param.IgnoreCheckSum = 1;
param.ReadMode = gmseBarcodeReadMode.WholeBitmap;
using (rotImg = new gmseBitmap(img.ExtractFrame(e)))
{
// do some basic image enhancement for better results
rotImg.ChangePixelFormat(System.Drawing.Imaging.PixelFormat.Format32bppArgb);
rotImg.SelectActiveFrame(e);
if (scanParameters[j].WholePage)
{
parseImage = rotImg.ExtractFrame(e);
}
else
{
using (tempImage = rotImg.ExtractFrame(e))
{
Rectangle convertedRect = returnConvertedRectangle(tempImage, scanParameters[j].Dimensions);
if (convertedRect.IntersectsWith(new Rectangle(0, 0, tempImage.Width, tempImage.Height)))
{
//GC.Collect(); //Test so I can see what objects are still alive in dump
parseImage = tempImage.CopyRectangle(convertedRect); //Exception here
}
}
}
}
//rotImg.Dispose();
//rotImg = null;
if (parseImage != null)
{
//Now we will apply the image enhancements:
if (scanParameters[j].Enhancements != ImageEnhancement.None)
{
rotImg = EnhanceImage(parseImage, scanParameters[j].Enhancements);
parseImage.Dispose();
parseImage = null;
}
if ((scanParameters[j].BarcodeScanDirection & ScanDirection.LeftToRight) != 0 && !cancelled)
{
if (parseImage == null)
{
tempImage = new gmseBitmap(rotImg.Image, 1);
}
else
{
tempImage = new gmseBitmap(parseImage.Image, 1);
}
bcc = tempImage.ReadBarcodes(param);
foreach (gmseBarcodeInfo bc in bcc)
{
addBarcode(codes, new object[] { searchCount, bc.Text, gmseBarcodeTypeConvert(bc.BarcodeType), scanParameters[j].ZoneName });
}
tempImage.Dispose();
tempImage = null;
}
if ((scanParameters[j].BarcodeScanDirection & ScanDirection.RightToLeft) != 0 && !cancelled)
{
if (parseImage == null)
{
tempImage = new gmseBitmap(rotImg.Image, 1);
}
else
{
tempImage = new gmseBitmap(parseImage.Image, 1);
}
tempImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
bcc = tempImage.ReadBarcodes(param);
foreach (gmseBarcodeInfo bc in bcc)
{
addBarcode(codes, new object[] { searchCount, bc.Text, gmseBarcodeTypeConvert(bc.BarcodeType), scanParameters[j].ZoneName });
}
tempImage.Dispose();
tempImage = null;
}
if ((scanParameters[j].BarcodeScanDirection & ScanDirection.TopToBottom) != 0 && !cancelled)
{
if (parseImage == null)
{
tempImage = new gmseBitmap(rotImg.Image, 1);
}
else
{
tempImage = new gmseBitmap(parseImage.Image, 1);
}
tempImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
bcc = tempImage.ReadBarcodes(param);
foreach (gmseBarcodeInfo bc in bcc)
{
addBarcode(codes, new object[] { searchCount, bc.Text, gmseBarcodeTypeConvert(bc.BarcodeType), scanParameters[j].ZoneName });
}
tempImage.Dispose();
tempImage = null;
}
if ((scanParameters[j].BarcodeScanDirection & ScanDirection.BottomToTop) != 0 && !cancelled)
{
if (parseImage == null)
{
tempImage = new gmseBitmap(rotImg.Image, 1);
}
else
{
tempImage = new gmseBitmap(parseImage.Image, 1);
}
tempImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
bcc = tempImage.ReadBarcodes(param);
foreach (gmseBarcodeInfo bc in bcc)
{
addBarcode(codes, new object[] { searchCount, bc.Text, gmseBarcodeTypeConvert(bc.BarcodeType), scanParameters[j].ZoneName });
}
tempImage.Dispose();
tempImage = null;
}
if (parseImage != null)
{
parseImage.Dispose();
parseImage = null;
}
if (rotImg != null)
{
rotImg.Dispose();
rotImg = null;
}
}
}
}
searchCount++;
if (cancelled) //If cancelled, end the loops
{
e = framecount;
dvCount = files.Length;
}
}
} //end using img
//img.Dispose();
//img = null;
}
}
catch (Exception ex)
{
message = ex.Message;
}
finally
{
if (img != null)
{
img.Dispose();
img = null;
}
if (rotImg != null)
{
rotImg.Dispose();
rotImg = null;
}
if (tempImage != null)
{
tempImage.Dispose();
tempImage = null;
}
if (parseImage != null)
{
parseImage.Dispose();
parseImage = null;
}
}
if (!String.IsNullOrEmpty(message))
throw new Exception(message);
return codes;
}
Мы используем этот подключаемый модуль GMSE Imaging для помощи при считывании штрих-кодов с распознавания при сканировании, он работает с перекосом, поворачивая изображение на 10 градусов, пока не получит чтение. Обнаружена ошибка, из-за которой при сканировании листов разного размера возникла ошибка.
Я проследил его от нашей основной программы до одной из наших библиотек DLL, где я обнаружил, что он перехватывает исключение OutOfMemoryException.
Исходный формат TIF составляет 300 КБ, но для поворота изображений выполняется достаточное количество копий. (между 4 растровыми изображениями)
Однако я проследил за программой и провел мониторинг местных жителей, и кажется, что каждое растровое изображение корректно распределяется и присваивается нулевое значение, прежде чем метод в циклах сбоев.
Я также пытался добавить GC.Collect()
в конце моего цикла.
Я на 32-битном компьютере W7, который, как я прочитал, имеет ограничение в 2 ГБ на объект, с обильным количеством оперативной памяти, так что ничего такого не хватает.
Я смотрел его в диспетчере задач, и мое использование оперативной памяти меняется только с 1,72 до 1,78 ГБ.
Это было сложно исследовать, так как OoM кажется необычной ошибкой.
Мне было интересно, есть ли у кого-нибудь совет по поводу такого исключения? Я не мастер Visual Studio, есть ли простой способ мониторинга ресурсов / использования памяти?
Или знает какие-либо утилиты, которые я могу использовать, чтобы помочь?
Вывод здесь сообщения об ошибке, не уверен, насколько полезны фрагменты кода в этой ситуации ...
System.OutOfMemoryException was caught
Message=Out of memory.
Source=System.Drawing
StackTrace:
at System.Drawing.Bitmap.Clone(Rectangle rect, PixelFormat format)
at gmse.Imaging.gmseBitmap.CopyRectangle(Rectangle r)
at ImagingInterface.ImagingFunctions.ParseBarcodes(String[] files, BarcodeZoneScan[] scanParameters) in C:\Working\Scan.backup\Global Dlls\v2.6.0.02\ScanGlobalDlls\ImagingInterface\ImagingFunctions.cs:line 632
InnerException:
(в настоящее время читаем больше в GC / Управление памятью http://msdn.microsoft.com/en-us/library/ee851764.aspx)
Работа над шагом этого руководства с использованием SOS-отладчика в окне Immediate с целью определения, сгенерировано ли исключение из управляемого или неуправляемого кода.
Шаги сверху показали, что это проблема с управляемым кодом, так как показан тип исключения из SOS.
Exception object: 39594518
Exception type: System.OutOfMemoryException
Message: <none>
InnerException: <none>
StackTrace (generated):
Heapdump, который я взял , похоже, не является тысячами растровых изображений, как я ожидал. Не уверен на 100%, как интерпретировать дамп, чтобы увидеть, что я могу найти на нем.
Не уверен, куда двигаться отсюда прямо сейчас! (Поиск ..)
редактирование:
Я пытался применить уроки в этом блоге к моей проблеме.
Начато с PerfMon
Этот график показывает мою программу от выполнения до того места, где она ловит исключение.
Первые два резких пика возникают после запуска синтаксического анализа отсканированного изображения, последнее выпадение происходит при обнаружении исключения.
В: Сравните кривые для виртуальных байтов, личных байтов и # байтов во всех кучах, следуют ли они друг за другом или они расходятся?
Каково значение #Bytes во всех кучах, расходящихся от? (Как его квартира на моем)
Проверенная память с адресом !summary
MEM_IMAGE соответствовал PrivateBytes (113 МБ) в значительной степени.
Q: Куда идет большая часть памяти (какой RegionType)?
RegionUsageFree 87,15%
RegionUsageIsVAF 5,64% (занято 43,89%) [память выделена через VirtualAlloc]
RegionUsageImage 5,54% (занято 43,13%) [Память, сопоставленная с файлом, который является частью исполняемого образа.]
В WinDbg с загруженной SOS я сделал! DumpHeap
//...
7063424c 1201 28824 System.Collections.ArrayList
706228d4 903 28896 System.EventHandler
7062f640 1253 30072 System.RuntimeType
6ec2be78 833 31216 System.Windows.Forms.PropertyStore+IntegerEntry[]
6ec2b0a4 654 34008 System.Windows.Forms.CreateParams
7063547c 318 35472 System.Collections.Hashtable+bucket[]
6ec2aa5c 664 37184 System.Windows.Forms.Control+ControlNativeWindow
70632938 716 40400 System.Int32[]
6c546700 48 49728 System.Data.RBTree`1+Node[[System.Data.DataRow, System.Data]][]
70634944 85 69600 System.Byte[]
6ec2b020 931 85972 System.Windows.Forms.PropertyStore+ObjectEntry[]
6c547758 156 161616 System.Data.RBTree`1+Node[[System.Int32, mscorlib]][]
705e6c28 2107 238912 System.Object[]
00305ce8 18 293480 Free
7062f9ac 5842 301620 System.String
Total 35669 objects
А вот и верхние объекты, занимающие память.
Я надеялся, что что-то высунется, как больной большой палец, как огромное количество растровых изображений или что-то в этом роде. Что-нибудь здесь кричит "Я веду себя необычно!" кому-нибудь?
(Я пытаюсь исследовать главные из них на предмет подозрительных вещей, но было бы неплохо еще немного сузить круг возможных виновников)
Эта страница (объяснение адреса объяснено) очень помогла.Однако C # - мой первый язык, поэтому у меня нет опыта отладки проблем с памятью.Хотелось бы узнать, нахожусь ли я на правильном пути ( Является ли ГХ проблемой вообще? ), поскольку я не нашел ничего, что давало бы мне какие-либо четкие указания.
Ответ: Проблема возникла в сторонней библиотеке.Я ничего не могу сделать.Обнаружено путем обдумывания и некоторых тестов с урезанным кодом, включающим только метод, выдающий ошибку.
Награда за то, что, как мне показалось, я выучил больше всего.