none
куда девается память RRS feed

  • Вопрос

  • День добрый!

    Прошу помощи... уже несколько дней воюю с кодом... упорно при работе программы растёт память и в итоге почти в конце варится в system.outofmemoryexception

    вот код функции которая выполняется:

    public void Export() { //if (Directory.Exists() const string fileName = "site_velikanauto.xml"; TextWriter w = new StreamWriter(fileName, false, Encoding.UTF8); w.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); w.WriteLine("<TradeInExport>"); using (var dc = new K20AppDataContext()) { string[] StatusList = new string[] { "Свободен", "Резерв", "ПСО" }; var stockQuery = from c in dc.Cars where StatusList.Contains(c.Status) select c; bool isMercedes = false; //Image ImgHeader = null;//.FromFile(img_name + ".jpg"); string img_auto = ""; Image ImgHeaderAutoRu = null; float currentImageWidth = 0; float currentImageHeght = 0; int needImageWidth = 0; int needImageHeight = 0; float relationW = 0; float relationH = 0; float relationValue = 0; float destWidth = 0; float destHeight = 0; Bitmap b = null; int i = 1; string img_name = "va"; foreach (var c in stockQuery) { try { isMercedes = false; if (c.ConfigModel.ConfigBrand.Name.Contains("Mercedes")) { isMercedes = true; } else isMercedes = false; w.Flush(); Console.Write("" + c.Id + " >>"); //****************** тут часть кода вырезал, не имеет отношения к проблеме...

    //************** идёт набор инструкций w.WriteLine("  текст XML");

    //************** w.WriteLine(" <Photos>"); i = 1; img_name = "va"; if (c.ReLocation_Car != null) { if (c.ReLocation_Car != 0) { if (c.ReLocation_Car == 2) img_name = "toyota"; if (c.ReLocation_Car == 7) img_name = "toyota-lub"; if (c.ReLocation_Car == 8) img_name = "vw"; if (c.ReLocation_Car == 3) img_name = "ford"; if (c.ReLocation_Car == 4) img_name = "lexus"; if (c.ReLocation_Car == 6) img_name = "mb"; } else { if (c.ConfigModel.ConfigBrand.Name == "Lexus") img_name = "lexus"; if (c.ConfigModel.ConfigBrand.Name == "Toyota") { if (c.ConfigLocation.Id == 2) img_name = "toyota"; if (c.ConfigLocation.Id == 7) img_name = "toyota-lub"; } if (c.ConfigModel.ConfigBrand.Name == "Ford") img_name = "ford"; if (c.ConfigModel.ConfigBrand.Name == "Volkswagen") img_name = "vw"; if (c.ConfigModel.ConfigBrand.Name == "Mercedes-Benz") img_name = "mb"; if (img_name == "va") { if (c.ConfigLocation.Id == 4) img_name = "lexus"; if (c.ConfigLocation.Id == 2) img_name = "toyota"; if (c.ConfigLocation.Id == 7) img_name = "toyota-lub"; if (c.ConfigLocation.Id == 8) img_name = "vw"; if (c.ConfigLocation.Id == 3) img_name = "ford"; if (c.ConfigLocation.Id == 6) img_name = "mb"; } } } else { if (c.ConfigModel.ConfigBrand.Name == "Lexus") img_name = "lexus"; if (c.ConfigModel.ConfigBrand.Name == "Toyota") { if (c.ConfigLocation.Id == 2) img_name = "toyota"; if (c.ConfigLocation.Id == 7) img_name = "toyota-lub"; } if (c.ConfigModel.ConfigBrand.Name == "Ford") img_name = "ford"; if (c.ConfigModel.ConfigBrand.Name == "Volkswagen") img_name = "vw"; if (c.ConfigModel.ConfigBrand.Name == "Mercedes-Benz") img_name = "mb"; if (img_name == "va") { if (c.ConfigLocation.Id == 4) img_name = "lexus"; if (c.ConfigLocation.Id == 2) img_name = "toyota"; if (c.ConfigLocation.Id == 7) img_name = "toyota-lub"; if (c.ConfigLocation.Id == 8) img_name = "vw"; if (c.ConfigLocation.Id == 3) img_name = "ford"; if (c.ConfigLocation.Id == 6) img_name = "mb"; } } img_auto = img_name + "_autoru"; ImgHeaderAutoRu = Image.FromFile(img_auto + ".jpg"); try { Console.Write(" F-"); //bool PhotosPresent = false;

    //собственно говоря затык где-то тут... где-то что-то не отчищаю...

    //память растёт как на дрожжах по мере прохождения цикла

    var Images = from pic in dc.CarPhotos where pic.Car_CarPhoto == c.Id && pic.MainPic select Image.FromStream(new MemoryStream(pic.DataStream.ToArray())); foreach (Image ImgDataStream in Images) { // Размеры текущего изображения currentImageWidth = ImgDataStream.Width; currentImageHeght = ImgDataStream.Height; // Размеры требуемого изображения needImageWidth = 1200; needImageHeight = Convert.ToInt32(currentImageHeght * 1200 / currentImageWidth); // Вычисляем отношение результирующего изображения к текущему relationW = ((float)needImageWidth / (float)currentImageWidth); relationH = ((float)needImageHeight / (float)currentImageHeght); // Переменная нужная для подгонки размера изображения relationValue = relationH < relationW ? relationH : relationW; // Определяем переменные размера изображения destWidth = (int)(currentImageWidth * relationValue); destHeight = (int)(currentImageHeght * relationValue); // Создаем объект в котором будет изображение и заполнитель b = new Bitmap(needImageWidth, needImageHeight); using (Graphics g = Graphics.FromImage((Image)b)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Рисуем изображение g.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight); //g.DrawImage(ImgHeaderAutoRu, 0, 0); if (!isMercedes && img_name != "mb") g.DrawImage(ImgHeaderAutoRu, 0, 0); if (isMercedes || img_name == "mb") g.DrawImage(ImgHeaderAutoRu, 0, destHeight - 105); //g.Dispose(); } b.Save(String.Format("Photo\\{0}-{1}.jpg", c.VIN, i), System.Drawing.Imaging.ImageFormat.Jpeg); i++; ImgDataStream.Dispose(); b.Dispose(); //GC.Collect(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); } Images = (from pic in dc.CarPhotos where pic.Car_CarPhoto == c.Id && !pic.MainPic && !pic.Name.Contains(".swf") select Image.FromStream(new MemoryStream(pic.DataStream.ToArray()))).Take(11-i); foreach (Image ImgDataStream in Images) { // Размеры текущего изображения currentImageWidth = ImgDataStream.Width; currentImageHeght = ImgDataStream.Height; // Размеры требуемого изображения needImageWidth = 1200; needImageHeight = Convert.ToInt32(currentImageHeght * 1200 / currentImageWidth); // Вычисляем отношение результирующего изображения к текущему relationW = ((float)needImageWidth / (float)currentImageWidth); relationH = ((float)needImageHeight / (float)currentImageHeght); // Переменная нужная для подгонки размера изображения relationValue = relationH < relationW ? relationH : relationW; // Определяем переменные размера изображения destWidth = (int)(currentImageWidth * relationValue); destHeight = (int)(currentImageHeght * relationValue); // Создаем объект в котором будет изображение и заполнитель b = new Bitmap(needImageWidth, needImageHeight); using (Graphics g = Graphics.FromImage((Image)b)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Рисуем изображение g.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight); //g.DrawImage(ImgHeaderAutoRu, 0, 0); if (!isMercedes && img_name != "mb") g.DrawImage(ImgHeaderAutoRu, 0, 0); if (isMercedes || img_name == "mb") g.DrawImage(ImgHeaderAutoRu, 0, destHeight - 105); } b.Save(String.Format("Photo\\{0}-{1}.jpg", c.VIN, i), System.Drawing.Imaging.ImageFormat.Jpeg); i++; ImgDataStream.Dispose(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); } foreach (CarPhoto p in (c.CarPhotos.Where(p => p.Name.Contains(".swf")).OrderBy(p => p.Name)).Take(1))

    { w.WriteLine(" <Photo3D>" + String.Format("{0}.swf", c.VIN) + "</Photo3D>"); using (FileStream fs = new FileStream(string.Format("Photo\\{0}.swf", c.VIN), FileMode.OpenOrCreate, FileAccess.Write)) { var fileData = p.DataStream.ToArray(); fs.Write(fileData, 0, fileData.Length); Console.Write(" 3D-OK "); } GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); //GC.Collect(); } if (i == 1) { Console.Write("NO"); w.WriteLine(" <Photo>" + String.Format("{0}-no.jpg", c.VIN) + "</Photo>"); Image ImgDataStream = Image.FromFile("nophoto.jpg"); // Размеры текущего изображения currentImageWidth = ImgDataStream.Width; currentImageHeght = ImgDataStream.Height; // Размеры требуемого изображения needImageWidth = 1200; needImageHeight = Convert.ToInt32(currentImageHeght * 1200 / currentImageWidth); // Вычисляем отношение результирующего изображения к текущему relationW = ((float)needImageWidth / (float)currentImageWidth); relationH = ((float)needImageHeight / (float)currentImageHeght); // Переменная нужная для подгонки размера изображения relationValue = relationH < relationW ? relationH : relationW; // Определяем переменные размера изображения destWidth = (int)(currentImageWidth * relationValue); destHeight = (int)(currentImageHeght * relationValue); // Создаем объект в котором будет изображение и заполнитель b = new Bitmap(needImageWidth, needImageHeight); using (Graphics g = Graphics.FromImage((Image)b)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Рисуем изображение g.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight); //g.DrawImage(ImgHeaderAutoRu, 0, 0); if (!isMercedes && img_name != "mb") g.DrawImage(ImgHeaderAutoRu, 0, 0); if (isMercedes || img_name == "mb") g.DrawImage(ImgHeaderAutoRu, 0, destHeight - 105); } b.Save(String.Format("Photo\\{0}-no.jpg", c.VIN), System.Drawing.Imaging.ImageFormat.Jpeg); // Создаем объект в котором будет изображение и заполнитель ДЛЯ АВТО.РУ /*var bb = new Bitmap(needImageWidth, needImageHeight); using (Graphics gg = Graphics.FromImage((Image)bb)) { gg.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Рисуем изображение gg.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight); gg.DrawImage(ImgHeaderAutoRu, 0, 0); } bb.Save(String.Format("Photo2Auto\\{0}-no.jpg", c.VIN, i), System.Drawing.Imaging.ImageFormat.Jpeg); bb.Dispose(); */ b.Dispose(); b = null; ImgDataStream.Dispose(); ImgDataStream = null; //GC.Collect(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); } Console.Write("OK"); } catch (Exception ex) { Console.WriteLine("" + c.Id + " Ошибка выгрузки фотографии!!! >> " + i + " >> " + ex.Message); } //if (PhotosPresent) //{ // Console.WriteLine(" Photos : reloaded!!!"); //} //else Console.WriteLine(" Photos : NOT reloaded!!!"); ImgHeaderAutoRu.Dispose(); ImgHeaderAutoRu = null; w.WriteLine(" </Photos>"); w.WriteLine(" </Car>"); Console.WriteLine(" <<"); } catch (Exception ex) { Console.WriteLine("" + c.Id + " Ошибка выгрузка автомобиля >> " + ex.Message); } } } //Console.ReadLine(); w.WriteLine("</TradeInExport>"); w.Close(); //Console.ReadLine(); }

    что я недоотчищаю? :(

    куда девается память?...

    даже в отладчике если смотреть программа может отваливаться в разных местах просто выдавая "Недостаточно памяти" или "выдано исключение типа  "System.OutOfMemoryException"" (кстати интересно почему то так то эдак?)

    Очень прошу помочь...

    • Перемещено YatajgaEditor 28 марта 2014 г. 15:49
    28 марта 2014 г. 13:53

Ответы

  • не там я копал...

    ларчик просто открывался... проблема была не в фотках а в коде который выгружал флэшки из БД...

                                var CarSWF = (from pic in dc.CarPhotos
                                                                  where pic.Car_CarPhoto == c.Id && pic.Name.Contains(".swf")
                                                                  select pic).Take(1).ToArray();
                                for (int k = 0; k < CarSWF.Length; k++)
                                {
                                    w.WriteLine("      <Photo3D>" + String.Format("{0}.swf", c.VIN) + "</Photo3D>");
    
                                    using (FileStream fs = new FileStream(string.Format("Photo\\{0}.swf", c.VIN), FileMode.OpenOrCreate, FileAccess.Write))
                                    {
                                        var fileData = CarSWF[k].DataStream.ToArray();
                                        fs.Write(fileData, 0, fileData.Length);
                                        Console.Write(" 3D-OK ");
                                        fileData = null;
                                    }
                                }
                                CarSWF = null;
                                //foreach (CarPhoto p in (c.CarPhotos.Where(p => p.Name.Contains(".swf")).OrderBy(p => p.Name)).Take(1))
                                ////foreach (var p in (c.CarPhotos.OrderBy(p => p.Name)).Take(5))
                                //{
                                //    w.WriteLine("      <Photo3D>" + String.Format("{0}.swf", c.VIN) + "</Photo3D>");
    
                                //    using (FileStream fs = new FileStream(string.Format("Photo\\{0}.swf", c.VIN), FileMode.OpenOrCreate, FileAccess.Write))
                                //    {
                                //        var fileData = p.DataStream.ToArray();
                                //        fs.Write(fileData, 0, fileData.Length);
                                //        Console.Write(" 3D-OK ");
                                //        fileData = null;
                                //    }
                                //    //GC.Collect();
                                //}

    то что закоментировано заменил на то что не закоммениторвано и всё... программа отработала не превышая 100Мб периодически отчищаясь до 20Мб....

    УРА! :)

    • Помечено в качестве ответа ITAlex 29 марта 2014 г. 11:36
    29 марта 2014 г. 11:35

Все ответы

    1. оффтоп: не понятно зачем трижды копировать код цикла - лучше бы оформить его как процедуру
    2. во втором цикле не хватает b.Dispose()
    3. помогать сборщику мусора не надо, он сам отлично справится
    4. да и следующая конструкция навевает сомнения (не уверен что MemoryStream удалиться при вызове Image.Dispose()):
    var Images = from pic in dc.CarPhotos
    where pic.Car_CarPhoto == c.Id && pic.MainPic
    select Image.FromStream(new MemoryStream(pic.DataStream.ToArray()));

    • Изменено nedel23 28 марта 2014 г. 14:22
    28 марта 2014 г. 14:10
  • ок...

    2 повтора вынес в отдельную процедуру...

    остальные пришлось оставить, они необходимы в том виде что есть...

    public void Export() { //if (Directory.Exists() const string fileName = "site_velikanauto.xml"; TextWriter w = new StreamWriter(fileName, false, Encoding.UTF8); w.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); w.WriteLine("<TradeInExport>"); using (var dc = new K20AppDataContext()) { string[] StatusList = new string[] { "Свободен", "Резерв", "ПСО" }; var stockQuery = from c in dc.Cars where StatusList.Contains(c.Status) select c; foreach (var c in stockQuery) { try { isMercedes = false; if (c.ConfigModel.ConfigBrand.Name.Contains("Mercedes")) { isMercedes = true; } else isMercedes = false; w.Flush(); Console.Write("" + c.Id + " >>"); w.WriteLine(" <Photos>"); i = 1; img_name = "va"; if (c.ReLocation_Car != null) { if (c.ReLocation_Car != 0) { if (c.ReLocation_Car == 2) img_name = "toyota"; if (c.ReLocation_Car == 7) img_name = "toyota-lub"; if (c.ReLocation_Car == 8) img_name = "vw"; if (c.ReLocation_Car == 3) img_name = "ford"; if (c.ReLocation_Car == 4) img_name = "lexus"; if (c.ReLocation_Car == 6) img_name = "mb"; } else { if (c.ConfigModel.ConfigBrand.Name == "Lexus") img_name = "lexus"; if (c.ConfigModel.ConfigBrand.Name == "Toyota") { if (c.ConfigLocation.Id == 2) img_name = "toyota"; if (c.ConfigLocation.Id == 7) img_name = "toyota-lub"; } if (c.ConfigModel.ConfigBrand.Name == "Ford") img_name = "ford"; if (c.ConfigModel.ConfigBrand.Name == "Volkswagen") img_name = "vw"; if (c.ConfigModel.ConfigBrand.Name == "Mercedes-Benz") img_name = "mb"; if (img_name == "va") { if (c.ConfigLocation.Id == 4) img_name = "lexus"; if (c.ConfigLocation.Id == 2) img_name = "toyota"; if (c.ConfigLocation.Id == 7) img_name = "toyota-lub"; if (c.ConfigLocation.Id == 8) img_name = "vw"; if (c.ConfigLocation.Id == 3) img_name = "ford"; if (c.ConfigLocation.Id == 6) img_name = "mb"; } } } else { if (c.ConfigModel.ConfigBrand.Name == "Lexus") img_name = "lexus"; if (c.ConfigModel.ConfigBrand.Name == "Toyota") { if (c.ConfigLocation.Id == 2) img_name = "toyota"; if (c.ConfigLocation.Id == 7) img_name = "toyota-lub"; } if (c.ConfigModel.ConfigBrand.Name == "Ford") img_name = "ford"; if (c.ConfigModel.ConfigBrand.Name == "Volkswagen") img_name = "vw"; if (c.ConfigModel.ConfigBrand.Name == "Mercedes-Benz") img_name = "mb"; if (img_name == "va") { if (c.ConfigLocation.Id == 4) img_name = "lexus"; if (c.ConfigLocation.Id == 2) img_name = "toyota"; if (c.ConfigLocation.Id == 7) img_name = "toyota-lub"; if (c.ConfigLocation.Id == 8) img_name = "vw"; if (c.ConfigLocation.Id == 3) img_name = "ford"; if (c.ConfigLocation.Id == 6) img_name = "mb"; } } //ImgHeader = Image.FromFile(img_name + ".jpg"); img_auto = img_name + "_autoru"; //img_auto = "toyota_autoru"; ImgHeaderAutoRu = Image.FromFile(img_auto + ".jpg"); try { Console.Write(" F-"); //bool PhotosPresent = false; var Images = from pic in dc.CarPhotos where pic.Car_CarPhoto == c.Id && pic.MainPic select Image.FromStream(new MemoryStream(pic.DataStream.ToArray())); foreach (Image ImgDataStream in Images) { CreateImageFromImg(ImgDataStream, c.VIN);

    ImgDataStream.Dispose(); } Images = (from pic in dc.CarPhotos where pic.Car_CarPhoto == c.Id && !pic.MainPic && !pic.Name.Contains(".swf") select Image.FromStream(new MemoryStream(pic.DataStream.ToArray()))).Take(11-i); //Where(p => p.MainPic == false && !p.Name.Contains(".swf")).OrderBy(p => p.Name)).Take(11 - i)) foreach (Image ImgDataStream in Images) { CreateImageFromImg(ImgDataStream, c.VIN);

    ImgDataStream.Dispose(); } foreach (CarPhoto p in (c.CarPhotos.Where(p => p.Name.Contains(".swf")).OrderBy(p => p.Name)).Take(1)) //foreach (var p in (c.CarPhotos.OrderBy(p => p.Name)).Take(5)) { w.WriteLine(" <Photo3D>" + String.Format("{0}.swf", c.VIN) + "</Photo3D>"); using (FileStream fs = new FileStream(string.Format("Photo\\{0}.swf", c.VIN), FileMode.OpenOrCreate, FileAccess.Write)) { var fileData = p.DataStream.ToArray(); fs.Write(fileData, 0, fileData.Length); Console.Write(" 3D-OK "); } GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); //GC.Collect(); } if (i == 1) { Console.Write("NO"); w.WriteLine(" <Photo>" + String.Format("{0}-no.jpg", c.VIN) + "</Photo>"); Image ImgDataStream = Image.FromFile("nophoto.jpg"); // Размеры текущего изображения currentImageWidth = ImgDataStream.Width; currentImageHeght = ImgDataStream.Height; // Размеры требуемого изображения needImageWidth = 1200; needImageHeight = Convert.ToInt32(currentImageHeght * 1200 / currentImageWidth); // Вычисляем отношение результирующего изображения к текущему relationW = ((float)needImageWidth / (float)currentImageWidth); relationH = ((float)needImageHeight / (float)currentImageHeght); // Переменная нужная для подгонки размера изображения relationValue = relationH < relationW ? relationH : relationW; // Определяем переменные размера изображения destWidth = (int)(currentImageWidth * relationValue); destHeight = (int)(currentImageHeght * relationValue); // Создаем объект в котором будет изображение и заполнитель b = new Bitmap(needImageWidth, needImageHeight); using (Graphics g = Graphics.FromImage((Image)b)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Рисуем изображение g.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight); //g.DrawImage(ImgHeaderAutoRu, 0, 0); if (!isMercedes && img_name != "mb") g.DrawImage(ImgHeaderAutoRu, 0, 0); if (isMercedes || img_name == "mb") g.DrawImage(ImgHeaderAutoRu, 0, destHeight - 105); } b.Save(String.Format("Photo\\{0}-no.jpg", c.VIN), System.Drawing.Imaging.ImageFormat.Jpeg); // Создаем объект в котором будет изображение и заполнитель ДЛЯ АВТО.РУ /*var bb = new Bitmap(needImageWidth, needImageHeight); using (Graphics gg = Graphics.FromImage((Image)bb)) { gg.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Рисуем изображение gg.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight); gg.DrawImage(ImgHeaderAutoRu, 0, 0); } bb.Save(String.Format("Photo2Auto\\{0}-no.jpg", c.VIN, i), System.Drawing.Imaging.ImageFormat.Jpeg); bb.Dispose(); */ b.Dispose(); b = null; ImgDataStream.Dispose(); ImgDataStream = null; //GC.Collect(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); } Console.Write("OK"); } catch (Exception ex) { Console.WriteLine("" + c.Id + " Ошибка выгрузки фотографии!!! >> " + i + " >> " + ex.Message); } //if (PhotosPresent) //{ // Console.WriteLine(" Photos : reloaded!!!"); //} //else Console.WriteLine(" Photos : NOT reloaded!!!"); ImgHeaderAutoRu.Dispose(); ImgHeaderAutoRu = null; w.WriteLine(" </Photos>"); w.WriteLine(" </Car>"); Console.WriteLine(" <<"); } catch (Exception ex) { Console.WriteLine("" + c.Id + " Ошибка выгрузка автомобиля >> " + ex.Message); } } } //Console.ReadLine(); w.WriteLine("</TradeInExport>"); w.Close(); //Console.ReadLine(); }


    функцию вынес отдельно...

            private void CreateImageFromImg(Image ImgDataStream, string VIN)
            {
                // Размеры текущего изображения
                currentImageWidth = ImgDataStream.Width;
                currentImageHeght = ImgDataStream.Height;
                // Размеры требуемого изображения
                needImageWidth = 1200;
                needImageHeight = Convert.ToInt32(currentImageHeght * 1200 / currentImageWidth);
                // Вычисляем отношение результирующего изображения к текущему
                relationW = ((float)needImageWidth / (float)currentImageWidth);
                relationH = ((float)needImageHeight / (float)currentImageHeght);
                // Переменная нужная для подгонки размера изображения
                relationValue = relationH < relationW ? relationH : relationW;
                // Определяем переменные размера изображения
                destWidth = (int)(currentImageWidth * relationValue);
                destHeight = (int)(currentImageHeght * relationValue);
                // Создаем объект в котором будет изображение и заполнитель
                b = new Bitmap(needImageWidth, needImageHeight);
                using (Graphics g = Graphics.FromImage((Image)b))
                {
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    // Рисуем изображение
                    g.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight);
                    //g.DrawImage(ImgHeaderAutoRu, 0, 0);
                    if (!isMercedes && img_name != "mb") g.DrawImage(ImgHeaderAutoRu, 0, 0);
                    if (isMercedes || img_name == "mb") g.DrawImage(ImgHeaderAutoRu, 0, destHeight - 105);
                }
                b.Save(String.Format("Photo\\{0}-{1}.jpg", VIN, i), System.Drawing.Imaging.ImageFormat.Jpeg);
    
                i++;
                b.Dispose();
                ImgDataStream.Dispose();
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                GC.WaitForPendingFinalizers();
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            }
    

    всё равно... память растёт...

    что ещё?

    28 марта 2014 г. 14:29
  • 1. Что говорит профайлер?

    2. Не помогать (а на деле - мешать) сборщику мусора.

    3. Для всех IDisposable-объектов вызывать Dispose() или использовать оператор using. Это Image, Bitmap, Stream, etc. nedel23 правильно заметил про MemoryStream.

    4. Не вижу в коде логирования. Именно по логам можно судить о проблемах.

    5. Мой дедушка рассказывал мне, что ему говорил прадед, как предавали анафеме за формирование xml вручную, используя запись в TextWriter/StreamWriter и конкатенацию строк. Используйте какой-нибудь XML API.

    6. Наймите программиста.

    28 марта 2014 г. 14:48
  • в разных местах просто выдавая "Недостаточно памяти" или "выдано исключение типа  "System.OutOfMemoryException"" (кстати интересно почему то так то эдак?)

    Нехватка памяти - это такое событие, которое влияет на всю систему. В одном случае раньше может произойти перехват исключение в вашем приложении, в другом случае - отладчиком VS, в третьем - самой ОС.
    28 марта 2014 г. 15:11
  • 2. Не помогать (а на деле - мешать) сборщику мусора.

    ок все инструкции GC.* удалил

    3. Для всех IDisposable-объектов вызывать Dispose() или использовать оператор using. Это Image, Bitmap, Stream, etc. nedel23 правильно заметил про MemoryStream.

    вот так будет лучше? (у меня складывается впечатление что не из-за картинок у меня память отжирается, а из-за объектов linq)

                                var CarsPhoto = from pic in dc.CarPhotos
                                                where pic.Car_CarPhoto == c.Id && pic.MainPic
                                                select pic;
                                foreach (CarPhoto _pic in CarsPhoto)
                                {
                                    MemoryStream memSteam = new MemoryStream(_pic.DataStream.ToArray());
                                    Image ImgDataStream = Image.FromStream(memSteam);
                                    CreateImageFromImg(ImgDataStream, c.VIN);
                                    ImgDataStream.Dispose();
                                    memSteam.Close();
                                    memSteam.Dispose();
                                }


    4. Не вижу в коде логирования. Именно по логам можно судить о проблемах.

    какое именно логирование вы подразумеваете?


    5. Мой дедушка рассказывал мне, что ему говорил прадед, как предавали анафеме за формирование xml вручную, используя запись в TextWriter/StreamWriter и конкатенацию строк. Используйте какой-нибудь XML API.

    6. Наймите программиста.

    ну пока что так... я понимаю что не красиво, но я не думаю что в данном случае утечка памяти из-за формирования XML... а по п.6 - мне ж тоже надо научится чему-то :)

    профайлер пока не смотрел... имеете ввиду SQL-евский?

    • Изменено ITAlex 29 марта 2014 г. 7:10
    29 марта 2014 г. 5:42
  • > вот так будет лучше?

    На первый взгляд да, всё правильно.

    > у меня складывается впечатление что не из-за картинок у меня память отжирается, а из-за объектов linq

    Класс CarPhoto реализует интерфейс IDisposable? Если да, то нужно вызывать Dispose и у него, когда становится ненужен.

    > какое именно логирование вы подразумеваете?

    В серьёзных приложениях по всему коду вставляют операции логирования: информация о текущем состоянии (а это может быть что угодно: входные параметры метода, текущие значения локальных переменных, объём занятой/свободной памяти и многое-многое другое) заносится в лог (это может быть и текстовый файл, и база данных, и что-то другое).

    Можно логировать просто с помощью stream.WriteLine. Но часто нужно делать это асинхронно, в другом потоке (чтобы не тормозить выполнение рабочего кода), желательно иметь возможность включать/отключать логирование изменением конфига и прочее. Поэтому существуют специальные фреймворки: NLog, log4net, а также родные средства дотнета: Logging Application Block, System.Diagnostics.Trace/TraceSource.

    Поначалу шокирует, но кода логирования может оказаться в итоге больше, чем кода бизнес-логики. Увы.

    Объём логов обычно тоже велик, зачастую набегают гигабайты. Для их анализа есть специальные утилиты.

    > ну пока что так... я понимаю что не красиво

    Ну мне поворчать же надо?

    > а по п.6 - мне ж тоже надо научится чему-то

    Я злой и вредный. Привыкайте.

    > профайлер пока не смотрел... имеете ввиду SQL-евский?

    Нет. Имеются в виду профилировщики именно .net-приложений. Например, бесплатный CLR Profiler от Microsoft. Существует куча других: dotTrace, ANTS, Scitech...

    В зависимости от того, какая у вас версия Visual Studio, в ней может быть встроенный профилировщик.

    29 марта 2014 г. 7:39
  • мой код притерпел следующие изменения, но результат всё тот же... память на 32 битной системе доходит примерно до 1,5Гб и приложение выдаёт исключение при попытке вытащить фото из БД...

    вот код основной функции:

            public void Export()
            {
                const string fileName = "site_velikanauto.xml";
                TextWriter w = new StreamWriter(fileName, false, Encoding.UTF8);
    
                w.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                w.WriteLine("<TradeInExport>");
    
                using (var dc = new K20AppDataContext())
                {
                    //dc.Log = Console.Out;
                    string[] StatusList = new string[] { "Свободен", "Резерв", "ПСО" };
    
                    var stockQuery = from c in dc.Cars
                                     where StatusList.Contains(c.Status)  
                                     select c;
    
    
                    foreach (var c in stockQuery)
                    {
                        try
                        {
                            isMercedes = false;
                            if (c.ConfigModel.ConfigBrand.Name.Contains("Mercedes"))
                            {
                                isMercedes = true;
                            }
                            else isMercedes = false;
    
                            w.Flush();
    
                            Console.Write("" + c.Id + " >>");
                            //if (c.Id == 4351)
                            //{
                            //    Console.WriteLine("123");
                            //}
                            //else
                            //{
                            //    continue;
                            //}
    
                            //Великан
                            w.WriteLine("  <Car>");
                            w.WriteLine("    <Photos>");
    
                            i = 1;
                            img_name = "va";
                            if (c.ReLocation_Car != null)
                            {
                                if (c.ReLocation_Car != 0)
                                {
                                    if (c.ReLocation_Car == 2) img_name = "toyota";
                                    if (c.ReLocation_Car == 7) img_name = "toyota-lub";
                                    if (c.ReLocation_Car == 8) img_name = "vw";
                                    if (c.ReLocation_Car == 3) img_name = "ford";
                                    if (c.ReLocation_Car == 4) img_name = "lexus";
                                    if (c.ReLocation_Car == 6) img_name = "mb";
                                }
                                else
                                {
                                    if (c.ConfigModel.ConfigBrand.Name == "Lexus") img_name = "lexus";
                                    if (c.ConfigModel.ConfigBrand.Name == "Toyota")
                                    {
                                        if (c.ConfigLocation.Id == 2) img_name = "toyota";
                                        if (c.ConfigLocation.Id == 7) img_name = "toyota-lub";
                                    }
                                    if (c.ConfigModel.ConfigBrand.Name == "Ford") img_name = "ford";
                                    if (c.ConfigModel.ConfigBrand.Name == "Volkswagen")
                                        img_name = "vw";
                                    if (c.ConfigModel.ConfigBrand.Name == "Mercedes-Benz") img_name = "mb";
    
                                    if (img_name == "va")
                                    {
                                        if (c.ConfigLocation.Id == 4) img_name = "lexus";
                                        if (c.ConfigLocation.Id == 2) img_name = "toyota";
                                        if (c.ConfigLocation.Id == 7) img_name = "toyota-lub";
                                        if (c.ConfigLocation.Id == 8) img_name = "vw";
                                        if (c.ConfigLocation.Id == 3) img_name = "ford";
                                        if (c.ConfigLocation.Id == 6) img_name = "mb";
                                    }
                                }
                            }
                            else
                            {
                                if (c.ConfigModel.ConfigBrand.Name == "Lexus") img_name = "lexus";
                                if (c.ConfigModel.ConfigBrand.Name == "Toyota")
                                {
                                    if (c.ConfigLocation.Id == 2) img_name = "toyota";
                                    if (c.ConfigLocation.Id == 7) img_name = "toyota-lub";
                                }
                                if (c.ConfigModel.ConfigBrand.Name == "Ford") img_name = "ford";
                                if (c.ConfigModel.ConfigBrand.Name == "Volkswagen")
                                    img_name = "vw";
                                if (c.ConfigModel.ConfigBrand.Name == "Mercedes-Benz") img_name = "mb";
    
                                if (img_name == "va")
                                {
                                    if (c.ConfigLocation.Id == 4) img_name = "lexus";
                                    if (c.ConfigLocation.Id == 2) img_name = "toyota";
                                    if (c.ConfigLocation.Id == 7) img_name = "toyota-lub";
                                    if (c.ConfigLocation.Id == 8) img_name = "vw";
                                    if (c.ConfigLocation.Id == 3) img_name = "ford";
                                    if (c.ConfigLocation.Id == 6) img_name = "mb";
                                }
                            }
                            //ImgHeader = Image.FromFile(img_name + ".jpg");
                            img_auto = img_name + "_autoru";
                            //img_auto = "toyota_autoru";
                            ImgHeaderAutoRu = null;
                            ImgHeaderAutoRu = Image.FromFile(img_auto + ".jpg");
    
                            try
                            {
                                Console.Write(" F-");
                                GetFirstCarPhoto(c.Id, c.VIN);
                                GetCarPhotos(c.Id, c.VIN);
                                foreach (CarPhoto p in (c.CarPhotos.Where(p => p.Name.Contains(".swf")).OrderBy(p => p.Name)).Take(1))
                                //foreach (var p in (c.CarPhotos.OrderBy(p => p.Name)).Take(5))
                                {
                                    w.WriteLine("      <Photo3D>" + String.Format("{0}.swf", c.VIN) + "</Photo3D>");
    
                                    using (FileStream fs = new FileStream(string.Format("Photo\\{0}.swf", c.VIN), FileMode.OpenOrCreate, FileAccess.Write))
                                    {
                                        var fileData = p.DataStream.ToArray();
                                        fs.Write(fileData, 0, fileData.Length);
                                        Console.Write(" 3D-OK ");
                                        fileData = null;
                                    }
                                    //GC.Collect();
                                }
    
                                if (i == 1)
                                {
                                    Console.Write("NO");
                                    w.WriteLine("      <Photo>" + String.Format("{0}-no.jpg", c.VIN) + "</Photo>");
    
    
                                    using (Image ImgDataStream = Image.FromFile("nophoto.jpg"))
                                    {
                                        // Размеры текущего изображения
                                        currentImageWidth = ImgDataStream.Width;
                                        currentImageHeght = ImgDataStream.Height;
                                        // Размеры требуемого изображения
                                        needImageWidth = 1200;
                                        needImageHeight = Convert.ToInt32(currentImageHeght * 1200 / currentImageWidth);
                                        // Вычисляем отношение результирующего изображения к текущему
                                        relationW = ((float)needImageWidth / (float)currentImageWidth);
                                        relationH = ((float)needImageHeight / (float)currentImageHeght);
                                        // Переменная нужная для подгонки размера изображения
                                        relationValue = relationH < relationW ? relationH : relationW;
                                        // Определяем переменные размера изображения
                                        destWidth = (int)(currentImageWidth * relationValue);
                                        destHeight = (int)(currentImageHeght * relationValue);
                                        // Создаем объект в котором будет изображение и заполнитель
                                        b = null;
                                        using (b = new Bitmap(needImageWidth, needImageHeight))
                                        {
                                            using (Graphics g = Graphics.FromImage((Image)b))
                                            {
                                                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                                                // Рисуем изображение
                                                g.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight);
                                                //g.DrawImage(ImgHeaderAutoRu, 0, 0);
                                                if (!isMercedes && img_name != "mb") g.DrawImage(ImgHeaderAutoRu, 0, 0);
                                                if (isMercedes || img_name == "mb") g.DrawImage(ImgHeaderAutoRu, 0, destHeight - 105);
                                            }
                                            b.Save(String.Format("Photo\\{0}-no.jpg", c.VIN), System.Drawing.Imaging.ImageFormat.Jpeg);
                                            b.Dispose();
                                        }
    ImgDataStream.Dispose();
                                    }
                                    //GC.Collect();
                                }
                                Console.Write("OK");
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("" + c.Id + " Ошибка выгрузки фотографии!!! >> " + i + " >> " + ex.Message);
                            }
                            //if (PhotosPresent)
                            //{
                            //    Console.WriteLine(" Photos : reloaded!!!");
                            //}
                            //else Console.WriteLine(" Photos : NOT reloaded!!!");
                            ImgHeaderAutoRu.Dispose();
                            ImgHeaderAutoRu = null;
                            w.WriteLine("    </Photos>");
                            w.WriteLine("  </Car>");
                            
                            Console.WriteLine(" <<");
                            //GC.SuppressFinalize(this);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("" + c.Id + " Ошибка выгрузка автомобиля >> " + ex.Message);
                        }
    
                    }
                }
    
                //Console.ReadLine();
    
                w.WriteLine("</TradeInExport>");
                w.Close();
                //Console.ReadLine();
            }
    

    вот переменные определенные в классе

            public float currentImageWidth = 0;
            public float currentImageHeght = 0;
            public int needImageWidth = 0;
            public int needImageHeight = 0;
            public float relationW = 0;
            public float relationH = 0;
            public float relationValue = 0;
            public float destWidth = 0;
            public float destHeight = 0;
            public Bitmap b = null;
            public int i = 1;
            public string img_name = "va";
            public bool isMercedes = false;
            //Image ImgHeader = null;//.FromFile(img_name + ".jpg");
            public string img_auto = "";
            public Image ImgHeaderAutoRu = null;

    вот вспомогательные функции:

            private void CreateImageFromImg(Image ImgDataStream, string VIN)
            {
                // Размеры текущего изображения
                currentImageWidth = ImgDataStream.Width;
                currentImageHeght = ImgDataStream.Height;
                // Размеры требуемого изображения
                needImageWidth = 1200;
                needImageHeight = Convert.ToInt32(currentImageHeght * 1200 / currentImageWidth);
                // Вычисляем отношение результирующего изображения к текущему
                relationW = ((float)needImageWidth / (float)currentImageWidth);
                relationH = ((float)needImageHeight / (float)currentImageHeght);
                // Переменная нужная для подгонки размера изображения
                relationValue = relationH < relationW ? relationH : relationW;
                // Определяем переменные размера изображения
                destWidth = (int)(currentImageWidth * relationValue);
                destHeight = (int)(currentImageHeght * relationValue);
                // Создаем объект в котором будет изображение и заполнитель
                using (b = new Bitmap(needImageWidth, needImageHeight))
                {
                    using (Graphics g = Graphics.FromImage((Image)b))
                    {
                        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                        // Рисуем изображение
                        g.DrawImage(ImgDataStream, 0, 0, destWidth, destHeight);
                        //g.DrawImage(ImgHeaderAutoRu, 0, 0);
                        if (!isMercedes && img_name != "mb") g.DrawImage(ImgHeaderAutoRu, 0, 0);
                        if (isMercedes || img_name == "mb") g.DrawImage(ImgHeaderAutoRu, 0, destHeight - 105);
                    }
                    b.Save(String.Format("Photo\\{0}-{1}.jpg", VIN, i), System.Drawing.Imaging.ImageFormat.Jpeg);
                    b.Dispose();
                }
                i++;
                ImgDataStream.Dispose();
            }
            private void GetFirstCarPhoto(int CarId, string VIN)
            {
                using (var _dc = new K20AppDataContext())
                {
                    _dc.ObjectTrackingEnabled = false;
                    var CarsPhoto = (from pic in _dc.CarPhotos
                                     where pic.Car_CarPhoto == CarId && pic.MainPic
                                     select pic).Take(1).ToArray();
                    for (int k = 0; k < CarsPhoto.Length; k++)
                    {
                        using (MemoryStream memSteam = new MemoryStream(CarsPhoto[k].DataStream.ToArray()))
                        {
                            using (Image ImgDataStream = Image.FromStream(memSteam))
                            {
                                CreateImageFromImg(ImgDataStream, VIN);
                                ImgDataStream.Dispose();
                            }
                            memSteam.Close();
                            memSteam.Dispose();
                        }
                    }
                    //foreach (CarPhoto _pic in CarsPhoto)
                    //{
                    //    MemoryStream memSteam = new MemoryStream(_pic.DataStream.ToArray());
                    //    Image ImgDataStream = Image.FromStream(memSteam);
                    //    CreateImageFromImg(ImgDataStream, c.VIN);
                    //    ImgDataStream.Dispose();
                    //    memSteam.Close();
                    //    memSteam.Dispose();
                    //    //GC.SuppressFinalize(this);
                    //}
    
                    CarsPhoto = null;
                }
            }
            private void GetCarPhotos(int CarId, string VIN)
            {
                using (var _dc = new K20AppDataContext())
                {
                    _dc.ObjectTrackingEnabled = false;
                    var CarsPhoto = ((from pic in _dc.CarPhotos
                                      where pic.Car_CarPhoto == CarId && !pic.MainPic && !pic.Name.Contains(".swf")
                                      select pic).Take(11 - i)).ToArray();
                    for (int k = 0; k < CarsPhoto.Length; k++)
                    {
                        using (MemoryStream memSteam = new MemoryStream(CarsPhoto[k].DataStream.ToArray()))
                        {
                            using (Image ImgDataStream = Image.FromStream(memSteam))
                            {
                                CreateImageFromImg(ImgDataStream, VIN);
                                ImgDataStream.Dispose();
                            }
                            memSteam.Close();
                            memSteam.Dispose();
                        }
                    }
                    CarsPhoto = null;
                }
            }

    а результат всё тот же... максимум всего убрал в конструктор using (){}

    всем объектам вроде делаю Dispose()

    переменные var в которые засовываю результат linq запроса к базе - когда они не нужны - приравниваю к null, НО такое ощущение что жрут память именно linq инструкции (или я не прав) и именно они висят в памяти...

    хелп нид :(

    29 марта 2014 г. 10:16
  • Класс CarPhoto реализует интерфейс IDisposable? Если да, то нужно вызывать Dispose и у него, когда становится ненужен.

    этот класс - это .. как сказать... у меня в БД есть таблица Cars т.е. автомобили... через linq как видно по коду я делаю выборку автомобилей, а в последствии делаю выборку фотографий данного автомобиля... так что CarPhoto это объект базы данных... и сам смотрел всё что можно о том как отчистить память занимаемую под эти объекты - и ничего кроме как засунуть их в ToArray() не придумал, а массив когда он больше не нужен обнулять (= null)... чуствую  *опой что где-то там проблем кроется... но пока ничего поделать не могу :(
    29 марта 2014 г. 10:21
  • не там я копал...

    ларчик просто открывался... проблема была не в фотках а в коде который выгружал флэшки из БД...

                                var CarSWF = (from pic in dc.CarPhotos
                                                                  where pic.Car_CarPhoto == c.Id && pic.Name.Contains(".swf")
                                                                  select pic).Take(1).ToArray();
                                for (int k = 0; k < CarSWF.Length; k++)
                                {
                                    w.WriteLine("      <Photo3D>" + String.Format("{0}.swf", c.VIN) + "</Photo3D>");
    
                                    using (FileStream fs = new FileStream(string.Format("Photo\\{0}.swf", c.VIN), FileMode.OpenOrCreate, FileAccess.Write))
                                    {
                                        var fileData = CarSWF[k].DataStream.ToArray();
                                        fs.Write(fileData, 0, fileData.Length);
                                        Console.Write(" 3D-OK ");
                                        fileData = null;
                                    }
                                }
                                CarSWF = null;
                                //foreach (CarPhoto p in (c.CarPhotos.Where(p => p.Name.Contains(".swf")).OrderBy(p => p.Name)).Take(1))
                                ////foreach (var p in (c.CarPhotos.OrderBy(p => p.Name)).Take(5))
                                //{
                                //    w.WriteLine("      <Photo3D>" + String.Format("{0}.swf", c.VIN) + "</Photo3D>");
    
                                //    using (FileStream fs = new FileStream(string.Format("Photo\\{0}.swf", c.VIN), FileMode.OpenOrCreate, FileAccess.Write))
                                //    {
                                //        var fileData = p.DataStream.ToArray();
                                //        fs.Write(fileData, 0, fileData.Length);
                                //        Console.Write(" 3D-OK ");
                                //        fileData = null;
                                //    }
                                //    //GC.Collect();
                                //}

    то что закоментировано заменил на то что не закоммениторвано и всё... программа отработала не превышая 100Мб периодически отчищаясь до 20Мб....

    УРА! :)

    • Помечено в качестве ответа ITAlex 29 марта 2014 г. 11:36
    29 марта 2014 г. 11:35
  • Посмотрите эту тему, она будет полезной для вас.

    Сделаем содержимое сообщества лучше, вместе!

    29 марта 2014 г. 11:49
    Модератор