Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
zakaz_77
9 / 9 / 4
Регистрация: 23.12.2015
Сообщений: 609
#1

Как уменьшить объём потребляемой оперативной памяти?

19.06.2017, 06:29. Просмотров 303. Ответов 10

Используется
C#
MySql

При добавлении в таблицу MySql новых записей растёт потребление оперативной памяти.

Код

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
            #region *** ЗАПРОС ***
            tbl_name = textBox115.Text; // Имя редактируемой таблицы. Пирсваиваем значение переменной
            sql_zpr_01 = "SELECT * FROM " + tbl_name; // Строка запроса
            #endregion *** ЗАПРОС ***
            
            sqlCom_0 = new MySqlCommand(sql_zpr_01, connMySql_db_2);
            sqlCom_0.ExecuteNonQuery();            
            MySqlDtAdp_0 = new MySqlDataAdapter(sqlCom_0);
            
            #region *** СОЗДАНИЕ ДТ ***
            dt_025 = new DataTable();            
            
            MySqlDtAdp_0.Fill(dt_025); // -> DataTable            
            #endregion *** СОЗДАНИЕ ДТ ***
            
            MySqlCommandBuilder commandBuilder = new MySqlCommandBuilder(MySqlDtAdp_0);
            
            
            int str; // кол. строк в пакете
            
            str = Convert.ToInt32(textBox123.Text); // кол. строк 
                for (int s = 1; s <= str; s++)
                {
                    name_str = textBox116.Text + "_" + s;
                    zpch_str = textBox117.Text + "_" + s;                
 
                    newRow = dt_025.NewRow();
                    newRow["name"] = name_str;
                    newRow["zpch"] = zpch_str;
                    dt_025.Rows.Add(newRow);
                }
                MySqlDtAdp_0.Update(dt_025);

Вопрос
Как уменьшить объём потребляемой оперативной памяти?

Дополню: при добавлении записей с использованием MySqlParameter увеличение потребления оперативной памяти не происходит.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.06.2017, 06:29
Ответы с готовыми решениями:

Как уменьшить объём потребляемой оперативной памяти программой?
Добавляю запись в таблицу MySql кодом private void insertData() { string...

Как уменьшить количество потребляемой памяти
Написал простенькую консольную програмку с несколькими классами. В диспечере...

Узнать, какой объём оперативной памяти занимает приложение
Можно ли каким-нибудь кодом узнать какой объём оперативной памяти занимает...

Как узнать объем оперативной памяти через реестр? (не используя сторонних программ)
мне нужно заполнить поле в базе данных значением объема оперативной памяти, на...

Загрузка ЦП и оперативной памяти
Добрый день. Я начал делать программу. Которая показывает загрузку ЦП и...

10
Usaga
Эксперт .NET
4881 / 3272 / 584
Регистрация: 21.01.2016
Сообщений: 12,884
Завершенные тесты: 2
19.06.2017, 07:36 #2
zakaz_77, метод MySqlDtAdp_0.Fill() сам выполнит запрос, не нужно его явно перед этим выполнять (sqlCom_0.ExecuteNonQuery();).

И кто вас научил такие беспонтовые имена сущностям давать? Давайте нормальные, осмысленные названия, а не всякую аббревиатуру как в конструкторской документации (dt_025, sqlCom_0).

В чём выражается "потребление памяти"? Как это замерялось? На глаз, в Task Manager?
1
hoolygan
349 / 276 / 76
Регистрация: 21.06.2016
Сообщений: 1,091
19.06.2017, 08:58 #3
Я тоже не увидел, в каком месте может такое уж большое увеличение памяти происходить.
Разве что в момент добавления строк в таблицу. Если это временная таблица - может быть есть смысл делать ей Dispose() в конце метода обновления.
Все строки, что добавляются в цикле - после каждой итерации и так будут убираться чистильщиком.
А так... ну фиг его знает.
1
zakaz_77
9 / 9 / 4
Регистрация: 23.12.2015
Сообщений: 609
21.06.2017, 12:24  [ТС] #4
Цитата Сообщение от Usaga Посмотреть сообщение
В чём выражается "потребление памяти"? Как это замерялось? На глаз, в Task Manager?
При запуске программы видно в диспетчере задач, что растёт память.

Цитата Сообщение от hoolygan Посмотреть сообщение
Если это временная таблица - может быть есть смысл делать ей Dispose() в конце метода обновления.
Дополнил код:
- добавил цикл;
- добавил Dispose();

Проблема осталась...
Хотя может я неправильно делаю..

Буду признателен. если поправите
Используем MySqlCommandBuilder КОД 1
Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// ПЕРЕМЕННЫЕ
DataTable  dt_027; 
BindingSource bs_027; 
 
 
#region *** ЗАПРОС ***
  tbl_name = textBox115.Text; // Имя редактируемой таблицы. Пирсваиваем значение переменной
  sql_zpr_01 = "SELECT * FROM " + tbl_name; // Строка запроса
#endregion *** ЗАПРОС ***
 
    sqlCom_0 = new MySqlCommand(sql_zpr_01, connMySql_db_2);
    sqlCom_0.ExecuteNonQuery();            
    MySqlDtAdp_0 = new MySqlDataAdapter(sqlCom_0);
 
#region *** СОЗДАНИЕ ДТ ***
  dt_025 = new DataTable();            
 
  MySqlDtAdp_0.Fill(dt_025); // -> DataTable            
#endregion *** СОЗДАНИЕ ДТ ***
 
MySqlCommandBuilder commandBuilder = new MySqlCommandBuilder(MySqlDtAdp_0);
 
int pac = Convert.ToInt32(textBox129.Text); // кол. пакетов
int str = Convert.ToInt32(textBox123.Text); // кол. строк в пакете
 
 
for (int p = 1; p <= pac; p++)
 {
 
    for (int s = 1; s <= str; s++)
    {
      name_str = textBox116.Text + "_" + s;
      zpch_str = textBox117.Text + "_" + s;                
 
      newRow = dt_025.NewRow();
      newRow["name"] = name_str;
      newRow["zpch"] = zpch_str;
      dt_025.Rows.Add(newRow);
    }
        
    MySqlDtAdp_0.Update(dt_025);
  // ПОПЫТКА ОЧИСТКИ ОЗУ
  // dt_025.Clear(); // ОЗУ. Растёт
  dt_025.Dispose(); // ОЗУ. Растёт
  
}



Также пробовал нижеприведённый код.
При использовании его оперативка не растёт
Использовать MySqlParameter КОД 2
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
            #region *** ПОДКЛЮЧЕНИЕ ***
            string serverName = textBox46.Text; // Адрес сервера (для локальной базы пишите "localhost")
            string userName = textBox47.Text; // Имя пользователя
            string dbName = textBox48.Text; //Имя базы данных
            string port = textBox49.Text; // Порт для подключения
            string password = textBox50.Text; // Пароль для подключения
 
            connStrMySql_db1 = "server=" + serverName +
               ";user=" + userName +
               ";database=" + dbName +
               ";port=" + port +
               ";password=" + password + ";";
 
            connMySql_db_2 = new MySqlConnection(connStrMySql_db1);
            connMySql_db_2.Open();
            #endregion *** ПОДКЛЮЧЕНИЕ ***
 
            #region *** ЗАПРОС ***
            // ПЕРЕМЕННЫЕ
            string tbl_name = "tst_027"; // ИМЯ ТАБЛИЦЫ
            string sps_pl = "name, zpch"; // список полей                                   
 
            string sql = string.Format(
                "INSERT INTO {0} ({1}) VALUES (@pol_1, @pol_2)",
                    tbl_name, sps_pl);
 
            #endregion *** ЗАПРОС ***
 
            MySqlCommand sqlCom = new MySqlCommand(sql, connMySql_db_2);
 
            #region *** ПАРАМЕТРЫ ***
            MySqlParameter prm_pol_1 = new MySqlParameter("@pol_1", MySqlDbType.VarChar);
            MySqlParameter prm_pol_2 = new MySqlParameter("@pol_2", MySqlDbType.VarChar);
 
            sqlCom.Parameters.Add(prm_pol_1);
            sqlCom.Parameters.Add(prm_pol_2);
 
 
            #endregion *** ПАРАМЕТРЫ ***
            
            int str = Convert.ToInt32(textBox130.Text); // кол. строк 
 
                for (int s = 1; s <= str; s++)
                {                
                    prm_pol_1.Value = textBox132.Text + "_" + s;
                    prm_pol_2.Value = textBox131.Text + "_" + 1;
 
                    sqlCom.ExecuteNonQuery();
                }
            }


ВОПРОС.
1. В чём может быть проблема?
2. Может не стоит морочится и использовать код с MySqlParameter?
Просто прочитал где-то здесь (Архитектура ПО в WinForms (FAQ & HowTo)),
что сначало нужно обработать данные в программе, а потом отправлять в нужное место.
Или я не правильно понял?
0
Usaga
Эксперт .NET
4881 / 3272 / 584
Регистрация: 21.01.2016
Сообщений: 12,884
Завершенные тесты: 2
21.06.2017, 12:49 #5
Цитата Сообщение от zakaz_77 Посмотреть сообщение
При запуске программы видно в диспетчере задач, что растёт память.
Это не мера расхода памяти. Это показания погоды в туалете. Особенно с CLR. Там память выделяется блоками, по мере надобности. Эти же блоки потом очищаются, но не обязательно, что возвращаются системе.

Воспользуйтесь профилировщиком для оценки реального расхода памяти. Или не грейте голову.
1
hoolygan
349 / 276 / 76
Регистрация: 21.06.2016
Сообщений: 1,091
21.06.2017, 14:50 #6
zakaz_77, Тут все очень запущено. На самом деле ни Вы , ни я точно не знаем, что зашито в коде адаптера, можем только пользоваться этим. Может быть там действительно косяк, который Вы и выявили. А дезасемблировать, чтобы докопаться - нафиг оно нужно
Цитата Сообщение от zakaz_77 Посмотреть сообщение
Просто прочитал где-то здесь (Архитектура ПО в WinForms (FAQ & HowTo)),
что сначало нужно обработать данные в программе, а потом отправлять в нужное место
А это уже интересно, но, думаю, Вы выдергиваете слова из контекста. Обрабатывать можно по-разному. Ведь мерджить таблицы - это же тоже обработка, но на стороне сиквела эта работа будет происходить на пару порядков быстрее по времени, чем на стороне клиента ) Так что все относительно.
1
zakaz_77
9 / 9 / 4
Регистрация: 23.12.2015
Сообщений: 609
21.06.2017, 18:26  [ТС] #7
Цитата Сообщение от Usaga Посмотреть сообщение
Это не мера расхода памяти. Это показания погоды в туалете.
))
Ну мне в принципе всё равно...
Факт, то что у меня начнёт тормозить комп.
Я правда не разгонял до максимума, но например если программе поставить задачу: добавить 30 000 строк, то результат роста ОЗУ будет выглядеть следующим образом. (см. скрин)
0
Миниатюры
Как уменьшить объём потребляемой оперативной памяти?  
Usaga
Эксперт .NET
4881 / 3272 / 584
Регистрация: 21.01.2016
Сообщений: 12,884
Завершенные тесты: 2
21.06.2017, 18:32 #8
zakaz_77, не совсем понятно, что вас удивляет. Вы нагружаете приложение данными, оно в ответ, выделяет память под эти данные. В чём противоречие? Не хотите расхода памяти - оптимизируйте код. Волшебства не бывает.
0
zakaz_77
9 / 9 / 4
Регистрация: 23.12.2015
Сообщений: 609
21.06.2017, 18:40  [ТС] #9
Usaga,
Прошу прощения, не совсем понимаю,в чём заключается оптимизация?

В сообщении #4 я привёл два варианта кода
- Используем MySqlCommandBuilder КОД 1 - потребляет ОЗУ
- Использовать MySqlParameter КОД 2 - не потребляет ОЗУ

ВОПРОС.

1. Можно ли сделать чтобы код "MySqlCommandBuilder КОД 1 " не потреблял ОЗУ?
0
HF
139 / 140 / 45
Регистрация: 09.09.2011
Сообщений: 493
Завершенные тесты: 18
21.06.2017, 18:54 #10
Цитата Сообщение от zakaz_77 Посмотреть сообщение
ВОПРОС.
1. В чём может быть проблема?
2. Может не стоит морочится и использовать код с MySqlParameter?
Просто прочитал где-то здесь (Архитектура ПО в WinForms (FAQ & HowTo)),
что сначало нужно обработать данные в программе, а потом отправлять в нужное место.
Или я не правильно понял?
1. Проблема в понимании процесса использования ресурсов и ссылок.
Первый пример Абсолютно нечитаемый. Я несколько раз его прошёлся сверху вниз и Не понял что же задумано программистом, что должно делаться. Какой-то Биндинг который нигде вроде бы не используется, какие-то загрузки и не понятно в какую сторону всё выгружается. Вроде бы Fill из базы, ан нет, потом идёт сборка таблицы зачем то. И в конце вообще не вижу никакой записи никуда. Обрезан код?
Сразу же увидел "код подозрительно похожий на ад".
C#
1
2
3
  // ПОПЫТКА ОЧИСТКИ ОЗУ
  // dt_025.Clear(); // ОЗУ. Растёт
  dt_025.Dispose(); // ОЗУ. Растёт
И это происходит в цикле, там же где чуть выше эта же таблица dt_025 постоянно добавляет строки. Конечно диспоза не будет, оно постоянно объект будет "оживлять". А попытки есть. Или я что-то не понимаю или это реально ад.

2. А вот второй вариант абсолютно читаемый и почти идеальный. Конечно же он не будет ничего отжирать. Каждые данные постоянно закидываются в таблицу, наращивания нигде не происходит. Не вижу критичных проблем во втором примере, особенно, по сравнению с первым.
Не помню какие есть возможности в MySQL, но в MsSQL можно использовать табличный параметр и сразу одним запросом всё закинуть, чтобы туда-сюда не бегать. Если такого нет, то можно максимально наращивать INSERT запрос и потом тоже оптом кидать. Короче избегать количественного обмена.

Моё мнение - второй пример должен быть рабочим, в рамках задачи и быстрого решения.

Добавлено через 2 минуты
Цитата Сообщение от zakaz_77 Посмотреть сообщение
1. Можно ли сделать чтобы код "MySqlCommandBuilder КОД 1 " не потреблял ОЗУ?
Если второй вариант идеален, а первый это жуть, то вы всё равно будете пытаться использовать путь первого варианта? Можете тогда обосновать это?
Наверняка можно, но нужно тогда понять зачем это всё там понаписано. Например с какой целью используется MySqlCommandBuilder?
0
Usaga
Эксперт .NET
4881 / 3272 / 584
Регистрация: 21.01.2016
Сообщений: 12,884
Завершенные тесты: 2
21.06.2017, 18:55 #11
zakaz_77, ну, в случае с кодом из поста #4 можно было бы работать с БД напрямую через ADO.NET, без всяких DataTable и DataAdapter. Более того, ваш код демонстрирует некую разновидность наркомании: вы сначала выполняете запрос (с косвенным получением данных драйвером СУБД), потом ещё один (строго тот же самый, но с полной загрузкой данных, в виде Fill()), и потом просто заносите данные в полученную таблицу с последующим сохранением в БД.

Самая первая оптимизация, что приходит на ум - подключение головного мозга к "обмозговыванию" кода и получению ответа на вопрос: какго хрена нужно дважды загружать некие данные, чтобы просто добавить в БД новые данные не имеющие отношения к загруженным?

Возможно после этого ваша программа станет меньше потреблять памяти...
0
21.06.2017, 18:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.06.2017, 18:55

Загрузка оперативной памяти
Пишу проект на C# связанный с базами данных. Необходимо мониторить то как...

Использование оперативной памяти
Создаю программу подсчета суммы элементов массива. Надо подсчитать врема...

Увеличение используемой оперативной памяти
Доброго времени суток. На C# была написана простая однокнопочная диалоговая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru