Witam,
Mam dosyć poważny wyciek pamięci w aplikacji. Po wielu testach doszedłem do tego, że prawdopodobnie spowodowany jest on przeładowywaniem danych we właściwości ItemsSource w obiekcie DataGrid.
Dla celów testowych uprościłem wszystko, stworzyłem odrębne okno z DataGridem (_grid) oraz Buttonem (_button).
Implementacja readera pobierającego dane z bazy danych Oracle jest bardzo prosta i wygląda tak jak poniżej (fragment klasy DbConnection):
public OracleDataReader ExecuteReader(string query)
{
try
{
using (OracleCommand sqlCommand = new OracleCommand(query, _sqlConnection))
{
return sqlCommand.ExecuteReader();
}
}
catch (OracleException ex)
{
throw ex;
}
}
Nie wiem na ile ma to duże znaczenie- ale przez cały czas życia aplikacji połączenie z bazą (obiekt _sqlConnection) jest otwarte
Inicjalizacja przycisku w konstruktorze wygląda następująco:
_button.Click += new RoutedEventHandler(test);
Obsługa kliknięcia wersja I (poniższy kod jeszcze nie powoduje wycieku pamięci):
private DataTable dataTable;
private DBConnection _dbconn; //to pole jest inicjowane gdzie indziej, ale obiekt jest dostępny w tym oknie
private void MemoryLeakTest(object sender, RoutedEventArgs e)
{
if(dataTable != null)
{
_dataTable.Clear();
}
_dataTable = new DataTable();
_dataTable.BeginLoadData();
_dataTable.Load(_dbconn.ExecuteReader("SELECT * FROM WORKERS"));
_dataTable.EndLoadData();
//_grid.ItemsSource = dataTable.DefaultView;
}
Obsługa kliknięcia wersja II (po usunięciu komentarza przypisującego DataView do grida powstaje wyciek pamięci)
private DataTable dataTable;
private DBConnection _dbconn; //to pole jest inicjowane gdzie indziej, ale obiekt jest dostępny w tym oknie
private void MemoryLeakTest(object sender, RoutedEventArgs e)
{
if(dataTable != null)
{
_dataTable.Clear();
}
_dataTable = new DataTable();
_dataTable.BeginLoadData();
_dataTable.Load(_dbconn.ExecuteReader("SELECT * FROM WORKERS"));
_dataTable.EndLoadData();
_grid.ItemsSource = dataTable.DefaultView;
}
Z każdym kolejnym kliknięciem na przycisk widać wyraźny wzrost pamięci. Wygląda to tak, jakby pole ItemSource nie było nigdy czyszczone z "historycznych" danych...
Dodam jeszcze, że przy wczytywaniu danych pobieram kilkaset wierszy z bazy danych- także raczej nie za wiele. Próbowałem również ręcznie czyścić wiersze przypisane do pola ItemSource ale nie wiele to zmienia.
Czy może ma ktoś pomysł jak pozbyć się tego problemu, i co tak na prawdę jest jego przyczyną?