Управление памятью VB.NET - PullRequest
       40

Управление памятью VB.NET

4 голосов
/ 13 сентября 2009

Обновление: я, вероятно, перепутал проблемы использования памяти с интерфейсом, использующим тот же поток, что и при обработке (как указано в MusiGenesis ниже). Однако относительно использования памяти. Я все еще не могу найти специфический синтаксис VB.net, хотя люди указали на некоторую отличную информацию .Net и C # ниже (и если бы я был более сведущ в этих технологиях, можно было бы приспособиться к работе с VB.net).

Я создаю приложение VB.Net.

  • Приложение в основном анализирует данные Файлы, расположенные на клиентском компьютере в DataSet / DataTables.
  • Затем с помощью DataView, он разбивает DataTables в управляемые куски, пишет в XML и отправляет данные XML в вебсервис.

Общие понятия работают нормально, однако у меня возникают проблемы, когда использование памяти в диспетчере задач продолжает расти, поскольку программа используется для загрузки все большего и большего количества файлов.

При запуске, прежде чем что-либо делать, приложение VB имеет 27 000 К. После того, как файл проанализирован, и даже после того, как я избавлюсь от дескриптора файла, данные также сильно возрастут. Я удаляю все в коде, и все еще кажется, что память в Mem Usage остается захваченной. Нет никакой рифмы или причины того, почему увеличивается использование памяти (т. Е. Иногда оно может увеличиваться на 20 МБ при чтении файла объемом 7 МБ, но в других случаях оно вообще не увеличивается при чтении файла 3 МБ). Иногда он освобождает некоторую память, когда синтаксический анализ завершен, а иногда просто удерживает.

Я смотрел на .Net Memory Profiler и на самом деле не смог сделать из этого головы или хвосты.
Я много читал в интернете об управлении памятью в .Net в целом об утилизации и "Nothing", а также о DataSets и т. Д., Но на самом деле ничего не нашел относительно VB.Net.

Мой общий вопрос : Существуют ли хорошие учебники / книги / блоги / и т. Д., В которых показано более подробное руководство по управлению памятью в приложении VB.Net (т. Е. Как / когда утилизировать / закрыть и т. д.), или у кого-нибудь есть какие-то конкретные советы оттуда опыта.

Ответы [ 5 ]

4 голосов
/ 13 сентября 2009

Во-первых, вы должны понимать, что диспетчер задач показывает вам объем памяти, выделенный операционной системой для вашего приложения. Это не обязательно тот объем памяти, который фактически используется. Когда приложение .NET запускается впервые, операционная система выделяет для него память, как и для любого процесса. Затем среда выполнения .NET дополнительно разделяет эту память и управляет ее использованием. Среда выполнения может рассматриваться как «жадная» в том смысле, что однажды выделенная память операционной системой не вернет ее, если она специально не будет запрошена операционной системой. В результате использование памяти в диспетчере задач не является точным.

Чтобы получить реальное представление об использовании памяти, вам необходимо использовать системный монитор и добавить соответствующие счетчики.

Что касается IDisposable и шаблона dispose, вы, вероятно, не найдете много такого, что говорит об этом в языковых терминах, поскольку это нечто, предоставляемое самой .NET Framework и не зависящее от языка. Шаблон один и тот же, независимо от того, какой язык вы используете, отличается только синтаксис.

Существует несколько ссылок, которые дадут вам информацию о том, как работает управление памятью. У меня есть две публикации в блоге, одна из которых посвящена Использование сборки мусора в .NET , а другая - списку различных ресурсов , которые я использовал для создания двух презентаций по управлению памятью в .NET.

Лучшее эмпирическое правило заключается в том, что если класс реализует IDisposable, он делает это по определенной причине, и вы должны убедиться, что вы вызываете Dispose(), когда вы закончите с использованием экземпляра. Это легче всего сделать с помощью оператора using.

3 голосов
/ 13 сентября 2009

Управление памятью в VB.Net фактически осуществляется платформой .Net Framework, поэтому в целом оно такое же в VB.Net, как и в C #. Однако понимание того, как это работает, позволяет вам принимать более правильные программные решения - когда объявлять переменные, когда располагаются объекты. В этом контексте я думаю, что ваш вопрос можно сформулировать так: «есть ли хорошие источники для того, чтобы рассказать мне, как эффективно кодировать и для меньшего объема памяти ", ИЛИ" Может кто-нибудь сказать мне, почему происходит эта странная штука ". На оба вопроса можно дать более полное представление о том, как .Net управляет памятью, областью действия и т. Д. Для этого существует множество ресурсов,

Тем не менее, у этой первой ссылки есть много других ссылок, которые будут вам полезны:

http://geekswithblogs.net/sdorman/archive/2008/09/14/.net-memory-management-ndash-resources.aspx

И этот второй вопрос ближе к делу:

http://www.c -sharpcorner.com / UploadFile / tkagarwal / MemoryManagementInNet11232005064832AM / MemoryManagementInNet.aspx

2 голосов
/ 14 сентября 2009

На вашем месте я бы в первую очередь использовал профилировщик, чтобы точно увидеть, что делает приложение. Их несколько - JetBrains, RedGate, YourKit. Оттуда вы можете точно увидеть, где память не освобождается.

Тогда вы можете увидеть, где именно вам нужно сосредоточиться, чтобы исправить проблему

1 голос
/ 13 сентября 2009

Это не ответ на ваш общий вопрос, но вы можете отправить DataTable напрямую в веб-сервис без промежуточного шага, прежде чем записать его в XML. На самом деле вы не можете отправить DataTable, но вы можете отправить DataSet (потому что DataSet является сериализуемым, а DataTable нет), поэтому вы можете отправить DataTable напрямую, сначала поместив его в DataSet, а затем отправка DataSet. Протокол SOAP в любом случае преобразует DataSet в XML, поэтому вы ничего не получите, если сами преобразуете DataTable в XML.

Я полагаю из вашего вопроса, что ваши DataTables слишком велики для одновременной отправки, иначе вы разбиваете их на более мелкие куски, чтобы ваше клиентское приложение могло показать прогресс пользователю. Это также может быть сделано без записи содержимого в XML самостоятельно.

Что касается вашего общего вопроса, неудивительно, что иногда ваше потребление памяти увеличивается на 20 МБ при чтении (и отправке) файла 7 МБ. XML, используемый для описания DataTable и его содержимого (независимо от того, делаете ли вы это самостоятельно или он автоматически сериализуется, когда вы отправляете его в веб-службу напрямую), является очень подробным.

Наиболее эффективный подход к этой проблеме - отправить файлы данных клиента непосредственно в веб-службу (либо в виде одного байта [] или в виде серии байтов []), а затем полностью обработать эти файлы сервер. Такой подход минимизирует время, необходимое для отправки каждого файла на сервер (поскольку отправка 7 МБ занимает меньше времени, чем отправка 20 МБ или даже больше).

0 голосов
/ 13 сентября 2009

Лучшая книга по теме, которую я прочитал, - книга Джеффа Рихтера, CLR через C #:

http://www.amazon.com/CLR-via-Second-Pro-Developer/dp/0735621632/ref=sr_1_1?ie=UTF8&qid=1252853101&sr=8-1-spell

Если вам нужна версия VB.NET, она есть для первого издания книги, но я не думаю, что было достаточно интереса перевести книгу на VB.NET для второй версии. Если вы действительно хотите изучать .NET, вы должны освоиться с C #. На обоих языках память управляется CLR.

...