Ответ 1
Он запускается успешно в первый раз, но если я запустил его снова, я продолжаю получать Исключение System.OutOfMemoryException. Какие это некоторые причины, по которым это может быть происходит?
Независимо от того, что говорили другие, ошибка не имеет никакого отношения к тому, чтобы забыть распоряжаться своим DBCommand или DBConnection, и вы не будете исправлять свою ошибку, удалив любой из них.
Ошибка имеет все, что связано с вашим набором данных, который содержит около 600 000 строк данных. По-видимому, ваш набор данных потребляет более 50% доступной памяти на вашем компьютере. Понятно, что у вас закончится память, когда вы вернете другой набор данных того же размера, прежде чем первый будет собран мусором. Просто как это.
Вы можете устранить эту проблему несколькими способами:
-
Рассмотрите возможность возврата меньшего количества записей. Я лично не могу представить себе время, когда возвращение 600K записей когда-либо было полезным для пользователя. Чтобы свести к минимуму возвращаемые записи, попробуйте:
-
Ограничение вашего запроса на первые 1000 записей. Если из запроса возвращено более 1000 результатов, сообщите об этом пользователю, чтобы сузить результаты поиска.
-
Если ваши пользователи действительно настаивают на том, чтобы сразу увидеть это много данных, попробуйте выполнить подкачку данных. Помните: Google никогда не показывает вам всего 22 бай-диона результатов поиска сразу, он показывает вам примерно 20 записей за раз. Google, вероятно, не сохраняет сразу все 22 баджона в памяти, вероятно, он считает, что более эффективно использовать память для создания своей новой базы данных.
-
-
Если вам просто нужно перебирать данные и вам не нужен произвольный доступ, попробуйте вместо этого вернуть datareader. Datareader загружает только одну запись в память за раз.
Если ни одна из них не является опцией, вам необходимо заставить .NET освободить память, используемую набором данных, прежде чем вызывать свой метод с помощью одного из этих методов:
-
Удалите все ссылки на старый набор данных. Все, что держится за обновление вашего набора данных, не позволит ему восстановить память.
-
Если вы не можете удалить все ссылки на свой набор данных, очистите все строки из набора данных и любые объекты, привязанные к этим строкам. Это удаляет ссылки на datarows и позволяет им съедаться сборщиком мусора.
Я не верю, что вам нужно вызвать GC.Collect()
, чтобы заставить цикл gen. Это не просто идея назвать GC.Collect()
, потому что достаточное давление памяти вызовет .NET, который вызовет сборщик мусора самостоятельно.
Примечание: вызов Dispose в вашем наборе данных не освобождает память и не вызывает сборщик мусора, а также не удаляет ссылку на ваш набор данных. Dispose используется для очистки неуправляемых ресурсов, но DataSet не имеет неуправляемых ресурсов. Он только реализует IDispoable, потому что он присущ MarshalByValueComponent, поэтому метод Dispose в наборе данных практически бесполезен.