Войти

Показать полную графическую версию : Борьба с утечками ресурсов.


Efsey
04-10-2010, 07:39
Заметил такую проблему в своей программе:

Программа осуществляет проверку файла на наличие необходимой записи каждые 2 минуты. Так вот, если проверок слишком много, то программа начинает разрастаться в оперативке (при ожидании около суток до 2 Гб). Где искать слабое место и как с этим бороться?

LilLoco
04-10-2010, 08:00
Возможно где нибудь ты забываешь закрыть какое нить соединение?!?!!?Где то просто наверное ресурсы не освобождаются, и поэтому происходит такое!!!Без кода вряд ли что то понять можно ;)

Efsey
04-10-2010, 08:05
Код:
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.Management;
using System.IO;
using WinFormsLesson;
using System.Threading;

namespace AutoBot
{
public partial class Form1 : Form
{
public int cho { get; set; }
public string str { get; set; }
public int X { get; set; }
FileStream logi;
public Form1()
{
InitializeComponent();
str = "";
cho = 0;
try
{
string imyaK = Environment.MachineName; //смотрит имя компа
X = int.Parse(imyaK.Substring(2, 1)); //переводит третий символ имени в формат цифры
X = X * 10;
this.rekursia();
}
catch //если имя не подходит происходит ошибка, но прога работает дальше
{
MessageBox.Show("Отказываюсь работать! У компа имя левое! Третий символ должен быть цифрой!", "АШЫБКА!!!!");
button1.Enabled = false; //шоб шалавливые ручки не пытались нажать
X = 50; //а вдруг все же нада запустить...
}
}
public void rekursia()
{
FormMsg frm = new FormMsg("Заголовок", "Сообщение", 30, ElapsedTimeButton.btnCancel);
if (frm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
//MessageBox.Show("Вы отказались запустить автоматический вариант о_0", "Ну и зачем?");
}
else
{
this.chitalka(); //если таймер не прервали, то запускается чтение логов, а при супер везении, то и запись дисков
}
} //окошко с таймером
private void avto()
{
try
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_LogicalDisk");
foreach (ManagementObject queryObj in searcher.Get())
{
string ghj = queryObj["Name"].ToString();
DriveInfo DI = new DriveInfo(ghj);
string dtip = '"' + ghj.Substring(0, 1) + '"';
DriveType CDR = DI.DriveType;
string tip = CDR.ToString(); //тип диска, сидюк там или флэха
string Name = DI.Name; //имя диска
string LabName;
if (ghj.Substring(0, 1) != "A") //флоппи за борт
{
if (ghj.Substring(0, 1) != "C") //систему тоже за борт
{
if (tip != "CDRom") //сидюки фтопку
{
LabName = DI.VolumeLabel; //метка тома
if (LabName != "") //если метка не пустая
{
X = X + 1;
string ArgCompiler;
string PathCompiler = "\\\\комп1\\прога.exe"; //адрес запускаемой проги
if (tip == "Removable") //если флеха
{
ArgCompiler = " -orderno=" + LabName + " -drive=" + ghj + " -id=" + X; //сюда нуна параметры для запуска проги
}
else //если просто HDD
{
ArgCompiler = " -hddlabel=" + LabName + " -drive=" + ghj + " -id=" + X; //сюда нуна параметры для запуска проги
}
System.Diagnostics.Process.Start(PathCompiler, ArgCompiler); //запуск писателя с аргументом
Thread.Sleep(10000); //уснуть на 10 сек
}
}
}
}
}
}
catch
{
this.avto(); //вылетело? пох, работать негр - солнце еще высоко!
}
finally
{
this.tamer(); //после всех запусков уснуть на 8 часов, а после запустить запись остатков
}
} //собстнна запись дисков
private void MainForm_Resize(object sender, System.EventArgs e)
{
if (FormWindowState.Minimized == WindowState)
{
notifyIcon1.Visible = true; //свернуть в трей
Hide();
}
}
private void button1_Click_1(object sender, EventArgs e)
{
this.avto();
}
public void tamer()
{
cho++;
if (cho < 7) //пока не было 7 запусков писателя
{
label1.Text = "отдыхаю";
Thread.Sleep(28800000); //уснуть на 8 часов (вдруг тада еще заказы будут)
this.rekursia();
}
else {MessageBox.Show("У меня перерыв после стольких попыток","Чёт я заипался работать :("); }//запустить запись остатков через 8 часов
}
public void chitalka()
{
try
{
FileStream fin;
string path = @"C:\Comb3\Combin.log";
if (File.Exists(path)) //а был ли файл
{
//string buf = File.ReadAllText(path, Encoding.Default);
int strok = 0;
fin = new FileStream(path, FileMode.Open, FileAccess.Read);
StreamReader fstr_in = new StreamReader(fin, Encoding.Default);
string s;
while ((s = fstr_in.ReadLine()) != null)
{
listBox1.Items.Add(s); // заполняем верхний листбокс
strok++;
}
fstr_in.Close();
strok = strok - 3;
if ((listBox1.Items[strok].ToString().Substring(21, 30)) == "Неслитых комбинаций не найдено")
{
//MessageBox.Show("УРРА НАШЕЛ");
this.avto(); //если строка найдена, то запускается запись
}
else
{
this.rekursia(); //если не найдено то запускает таймер
}
label1.Text = str;
}
else { MessageBox.Show("Нету логов", "Какая то лажа"); }
}
catch (IOException exc) { this.rekursia();} //если буит какая нить ошибка
catch (Exception exc) { this.rekursia();} //та же лажа
}
private void button3_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void button2_Click(object sender, EventArgs e)
{
notifyIcon1.Visible = true;
Hide();
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
Show();
WindowState = FormWindowState.Normal;
notifyIcon1.Visible = false;
} //выводит окно из трея
private void button4_Click(object sender, EventArgs e)
{
this.chitalka();
} //запуск чтения логов
}
}

Delirium
04-10-2010, 09:22
1. Рекурсивно вызывается форма FormMsg frm, но далее она нигде не обнуляется.
2. Есть System.Diagnostics.Process.Start, но нигде нет прерывания работы.
3. searcher также не удаляется, каждый раз создается новый.
В общем, ни одна переменная или процесс не заканчивают свою работу.

Efsey
04-10-2010, 09:36
1. Рекурсивно вызывается форма FormMsg frm, но далее она нигде не обнуляется. »
А как это делается?

2. Есть System.Diagnostics.Process.Start, но нигде нет прерывания работы. »

То есть завершения вызванной программы? Она сама выключается.

3. searcher также не удаляется, каждый раз создается новый. »

Он запускается только при условии что для этого готово (не более 7 раз)

И еще вопрос - листбокс надо обнулять, или там все замещается?

Delirium
04-10-2010, 09:44
А как это делается? »
frm = null;

То есть завершения вызванной программы? Она сама выключается. »
А проверить?

fin = new FileStream(path, FileMode.Open, FileAccess.Read);
Открыли файлик и висиииииим в памяти. fin.close() нигде не вызывается.

Согласно коду, даже если есть какое то исключение, программа все равно работает. Это в корне неверно. Надо отлавливать такие исключения и обрабатывать их, а не игнонировать.

Efsey
04-10-2010, 11:02
frm = null; fin.close(); listBox1.Items.Clear(); всё сделал, а прога все равно растет в оперативе, уже меньше, но все равно растет.
Где еще могут быть проблемы?

Efsey
04-10-2010, 15:01
Правильно ли будет занулять форму подобным образом?

public void rekursia()
{
FormMsg frm = new FormMsg("Заголовок", "Сообщение", 30, ElapsedTimeButton.btnCancel);
if (frm.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
frm = null;
//MessageBox.Show("Вы отказались запустить автоматический вариант о_0", "Ну и зачем?");
}
else
{
frm = null;
this.chitalka(); //если таймер не прервали, то запускается чтение логов, а при супер везении, то и запись дисков
}
}

Delirium
06-10-2010, 01:04
Можно и так. Но обнуление формы - это мелочь. Главная проблема в том, что при возникновения исключений вы не пытаетесь их обработать, а просто вжесткую еще раз запускаете процедуры. Плюс процедуры рекурсивные, но сбор мусора(Garbage Collection) нигде не происходит после отработки функций. И я бы рекомендовал не "усыплять" прогу, а сделать ее службой и пересмотреть алгоритм работы. Гораздо надежней не "ждать" 8 часов, а просто активироваться/запускаться в определенное время.




© OSzone.net 2001-2012