#c# #asp.net #garbage-collection #datatable
#c# #asp.net #сбор мусора #поддающийся обработке данными
Вопрос:
Мое приложение работает 24X7, и я использую DataTable для обработки данных.
Мне нужно каждый раз удалять DataTable. Я использовал методы Dispose и Clear, но содержимое только очищается, а его экземпляр все еще находится в памяти, когда я отлаживал код.
Как я могу удалить его из памяти, не завися от GC?
Заранее благодарю..
РЕДАКТИРОВАТЬ: Это мой прототип кода. я сделал это двумя способами.
1 //Methord 1
2 while (true)
3 {
4 DataTable dt = new DataTable();
5 dt.Columns.Add("City", typeof(string));
6 dt.Rows.Add("ABC");
7 dt.Rows.Add("XYZ");
8 dt.Rows.Add("PQR");
9 dt.Rows.Add("LMN");
10 dt.Dispose();
11 }
12 //Methord 2
13 while (true)
14 {
15 using (DataTable dtable = new DataTable())
16 {
17 dtable.Columns.Add("City", typeof(string));
18 dtable.Rows.Add("ABC");
19 dtable.Rows.Add("XYZ");
20 dtable.Rows.Add("PQR");
21 dtable.Rows.Add("LMN");
22 }
23 }
как будет удален объект данных? если вы проверите с помощью точки останова, вы все еще можете увидеть, что datatable ‘dt’ все еще имеет значения даже после вызова dispose() .даже при выполнении строки 11 значений все еще нет. мне нужно освободить эту память перед выполнением строки 12 (или перед 2-й итерацией while). что мне здесь делать?
Комментарии:
1. потому что мое приложение работает 24X7, а datatable занимает много памяти . на самом деле это в цикле. gc будет собираться только при выходе из программы, чего не происходит в моем приложении. а также я не могу дождаться, пока gc соберется, когда память будет заполнена.
2. Можете ли вы показать код цикла? Это могло бы помочь нам понять, что происходит.
3. GC не происходит «только при выходе из программы». Я думаю, что у вас здесь какая-то фундаментальная путаница в GC
4. У вас сейчас проблемы с памятью? Например, не хватает памяти?
Ответ №1:
Если вы установите для каждой ссылки на datatable значение nothing / null, базовые данные могут быть собраны мусором. Когда объект теряется, платформа dotnet автоматически собирает мусор, когда считает это целесообразным.
Вы можете указать сборщику мусора собирать данные вручную, но он будет собирать данные только для объектов, на которые нет ссылки в коде. http://msdn.microsoft.com/en-us/library/xe0c2357.aspx
Краткое описание того, как работает dotnet GC. http://dotnetfacts.blogspot.com/2008/05/how-garbage-collector-works-part-1.html
Если сборщик мусора не освобождает память, это, вероятно, потому, что другие объекты, элементы управления пользовательского интерфейса / другие бизнес-объекты, которые вы, возможно, написали, имеют ссылки на данные строки в вашей таблице данных. Например, вы отображаете данные строки или передаете строку в другой объект, и у него есть ссылка на эту строку.
Если у вас постоянно увеличивается объем памяти, у вас есть утечка памяти, т. Е. У вас постоянно увеличивается количество объектов, на которые есть ссылки, и фреймворк не может собирать мусор из этих данных, потому что он думает, что он используется. Вам нужно будет взглянуть на свой код и попытаться выяснить, почему он протекает, может помочь профилировщик памяти.
Комментарии:
1. спасибо за предложение.. но если я вообще установил Datatable=null, его снова оставили для GC. и GC выполняет сборку мусора при 1) выходе из программы или 2) при нехватке памяти. я не хочу, чтобы мое приложение потребляло всю память и освобождало ее при заполнении
2. Вы можете вызвать GC.collect(), чтобы запустить это вручную. Но если у вас утечка памяти, вам нужно найти основную причину проблемы, потому что вызов GC вручную вам не поможет
3. Сбор мусора не происходит при выходе из программы так, как вы описываете. То, что вы описываете, — это утечка памяти, т.Е. Потребляется память, и она перестает потребляться только при закрытии приложения. Вам нужно устранить утечку, и проблема исчезнет.
4. я попробовал pplication для проверки утилизации и GC с использованием IDisposable. и то, что я обнаружил, это то, что gc выполнялся только при выходе из программы. я ссылался на некоторые документы. в нем говорится, что gc освободит память при нехватке памяти. не могли бы вы, пожалуйста, помочь мне, где я ошибся..
5. Проблема будет заключаться в утечке памяти. GC будет выполняться чаще, но он не сможет очистить память, потому что там будет ссылка на объект. Вам нужно устранить утечку проблема с GC маскирует реальную проблему
Ответ №2:
Вы не можете удалить его из памяти, не завися от GC. Это будет зависеть от GC, когда и как освободить память. GC работает неопределенным образом, что означает, что вы не можете быть уверены, когда GC действительно освободит экземпляр
Вы должны просто убедиться, что вы не сохраняете никаких ссылок на DataTable, когда они больше не нужны. Если вы выполнили эту часть правильно, т.Е. Нет ссылки на DataTable, если это не требуется, тогда все в порядке и оставьте rest на GC
Комментарии:
1. то, что вы сказали, правильно. вы сказали, что GC будет работать неопределенным образом. но, насколько я знаю, gc будет делать это при выходе из программы или при нехватке памяти. я прав в этом?
2. Да, это так. Я думаю, что это не единственные два раза, когда GC это сделает. Я не уверен, что придется читать о том, когда именно срабатывает GC
Ответ №3:
Я сомневаюсь, что это хороший дизайн, чтобы попробовать rebuid, что GC делает в любом случае. Почему бы вам просто не запустить задачу цикла, которая выполняется 24/7, которая просто запускает процесс как новый поток? Когда поток будет завершен, вы можете уничтожить его, и в результате у вас не будет проблем с памятью.
Ответ №4:
Для его полного удаления потребуется сборка мусора, но если он вам больше не нужен, вы всегда можете установить для него значение null.
//do some stuff with the table
//don't need it any longer so set it null
table = null;
Ответ №5:
Вместо вызова метода dispose вы всегда можете обернуть саму таблицу данных в блок using:
using (DataTable dt = new DataTable())
{
//Do work here
}
Это гарантировало бы, что он будет очищен, когда сам объект выйдет за пределы своей области.
Статья MSDN сама по себе является очевидным ресурсом, если вы никогда не использовали ее раньше, но идея очень проста.
Комментарии:
1. ‘using’ вызывает Dispose() в фоновом режиме. Dispose уведомляет GC. И GC освободит память только 1) когда память заполнена или 2) при выходе из программы. Так что проблема все еще остается..
2. @Girish K G: вызов метода Dispose() не «уведомляет GC». Dispose похож на любой обычный метод. Объект является мусором, собранным, когда на него больше нет ссылок.
3. Сборщик мусора немного похож на действительно эффективный сборщик мусора / мусора / мусора в реальном мире. Вы используете объект в течение определенного периода времени, и в конце концов вы перестаете его использовать, он лежит где-то неиспользуемым. Время от времени приходит сборщик мусора и наводит порядок. Ваше приложение работает 24/7 сборщик мусора приходил сотни раз в день и решил, что этот объект используется…