Vba excel очистка памяти

Обновлено: 07.07.2024

Dim l As New clsSequinentalListItem
Dim n As clsSequinentalListItem
Set n = l
Set l = Nothing
MsgBox n Is Nothing

концептуальнейшая утечка )))))))))))а если . тьфу, тьфу, тьфу. объявили
Dim s As String * 65526
MsgBox Len(s)

то утечка составит почти Hex(65526) байт !

Теперь по существу вашего вопроса.
Вероятно, экземпляр вашего элемента списка выглядит как класс,
в области глобальных переменных которого содержится строковая переменная.
Ваш впрос - что будет происходить при уничтожении такого объекта.

Ответ тут из четырех частей состоит.
1) обычная строковая переменная устроена так, что про адресу этой переменной содержится адрес начала строки. Т.е. по существу это переменная типа ссылки.
Освобождая память, занятую освободившимся объектом, VBA по "задумке" и "философии" языка не только освобождает память, занятую адресом начала строки, но и память, занятую самой строкой. т.е. в вашем случае освободится память, отведенная как под сам объект, так и под строку, на которую ссылается его переменная, ЕСЛИ.

2) Если вы используете Офис версиии 2000 или позже (с пропатченным до "хорошего" уровня VBA).
К сожалению, в любых реализациях есть баги. первоначальные версии особенно 95 и даже 97го офиса могли дурить в этом месте. В любом случае, если вы не доверяете встроенному механизму освобождения строковой памяти при освобождении объекта, вы можете собственноручно освободить строковую память в деструкторе класса присвоением строковой переменной значения vbNullString. Такое присвоение гарантированно поднимет механизм освобождения занятой строковой памяти по завершении деструктора. Если вы работает с "нормальным" vba он и так гарантированно поднимется, но, может быть, читатель вашего кода оценит, что вы помните о
вопросах освобождения памяти и специально аккуратно позаботились об этом в деструкторе.
(деструктор - это событийная процедура Class_Terminate, которая запускается автоматически сразу при обнулении счетчика ссылок, а не как в Java - когда, ("подождав полдня"), до ее запуска доберется сборщик мусора. )

PS1.Вы помянули Redim - оператор выделения памяти для массивов. Обратный ему - освобождения памяти для массивов - Erase

3) Хотя строка и является простым типом данных в VBA, механизм их поддержки полностью берется из набора поддержки строковых функций COM, это значит, что за отсутствием сборщика мусора, который реорганизует занятую память, может возникать дефрагментация.
Пусть у вас есть три последовательно создававшихся объекта, ссылающихся на строки "ааа", "ббббб", "ввввввв".
Тогда система выделит под них память примерно так:
3ааа5ббббб7ввввввв

Вы уничтожаете объект 2 и память занятая строкой "ббббб" освобождается. Условная структура памяти становится такой
3аааа0000007ввввввв
если теперь вы создаете новый объект, который должен ссылаться на строку "ссссссссс", то система не сможет использовать под нее память, освоюожденную от строки "ббббб", так как строковая память выделяется только непрерывными диапазонами, а в освобожденном куске нет места, для размещения новой строки целиком.
Новая структура памяти будет такой.
3аааа0000007ввввввв9ссссссссс

Этот вопрос возник в другой теме. Но он важен сам по себе. Я не спец. И много здесь "неспецов". Но есть СПЕЦЫ. И на вас, братки, уповаем. Есть ли стандартные прибамбасы (программы, модули) для поиска источников утечки памяти в VBA-проектах? Думаю, что это полезно всем: как при создании монстроприложений, так и просто для привития привычки к порядку при програмировании.

Добавлено через 15 минут
для начала как их увидеть?

Борьба с утечками памяти
Знаю, что вроде бы есть дополнения к Студии, с помощью которых можно отслеживать утечки. Или.

Что делать с утечками памяти?
С этими утечками памяти в C++ просто беда. Посоветуйте, что можно сделать? Может быть есть какие-то.

Как бороться с утечкой памяти?
Добрый день! у меня такая проблема: в моей программе видимо где-то проблемы с утечкой памяти. если.

стандартные прибамбасы (программы, модули) для поиска источников утечки памяти 1.Стандартным прибамбасом для поиска утечки является сухая тряпка.
2.Что бы память не утекала необходимо жидкий диск поменять на жесткий.Правда есть один недостаток - теперь память будет осыпаться.Что бы этого избежать,необходимо не забывать ее обильно смачивать.
. Ничего личного,просто навеяло.

А если серьезно,не понятно,что вы имеете ввиду под утечкой памяти? Надо следить за форумом. В предыдущей теме было начало.

Ребята. надо следить не только за этим форумом.
Из википедикулёза читаем:

Добавлено через 5 минут
Это - стандартный термин, применимый для таких писак программ как я, которые "не всё" контролируют. Но мне - простительно. Из профильного образования у меня - только журнал "Наука и жысть". Причем тех годов, когда "Пятихата" в СССР из-под полы продавалась. Для семейства сишных программ есть куча стандартных прог, отслеживающих такие неконтролируемые потери памяти. Я сегодня кучу описаний к ним прочитал. а вот к VBA - таких не нашел. Может кто умный знает - как мышу ловить? Вот об этом я и спрашиваю.

Добавлено через 2 минуты
кстати, хорошим примером утечки памяти является пример когда две функции вызывают друг друга в цикле. Вот вам и нету в итоге памяти. Зато в стеке - такое дерево - мама, не горюй, папа, не матерись!

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

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

Как очистить кеш Excel

К счастью, большинство программ в настоящее время позволяют очистить кеш. Пакет программ Microsoft Office, в частности Excel, не является исключением. Читайте дальше, чтобы узнать, как освободить кэш Excel.

Отключить список последних документов

Очистить кеш сводной таблицы

Среди наиболее важных параметров очистки кэша, специфичных для Excel, есть те, которые позволяют очистить кэш сводной таблицы. При этом удаляются старые, неиспользуемые элементы. Есть два способа сделать это.

Использование параметров сводной таблицы

  1. Кликните правой кнопкой мыши ячейку в сводной таблице. Появится контекстное меню.


Использование кода VBA

Для этого вы также можете использовать программу Microsoft Visual Basic для приложений. Основным преимуществом этого метода является то, что он охватывает все сводные таблицы.

    Откройте файл, для которого вы хотите очистить кеш сводных таблиц, нажмите Alt + F11, чтобы открыть Microsoft Visual Basic для приложений.


Очистка кэша Office вручную

Используйте Центр загрузки Office

Вы можете использовать программу Microsoft Office Upload Center, чтобы вручную очистить кэш для всех программ Office. В версиях Windows 7 и 10 вы можете найти это приложение, введя его имя в строке поиска меню «Пуск».

В Windows 8 и 8.1 доступ к параметру поиска осуществляется при наведении курсора мыши на правый нижний угол экрана. Это будет один из предложенных вариантов.


    Откройте Центр загрузки и нажмите кнопку «Настройки».


Примечание. Вы также можете установить параметр «Дни хранения файлов в кэше документов Office» по своему усмотрению.

Использовать очистку диска

Программа очистки диска Windows помогает удалять временные файлы всех видов, включая документы Office. Очистку диска можно найти так же, как и Центр загрузки Office.


Как часто вы очищаете кеш в Excel? Excel работает быстрее? Как это влияет на ваш компьютер? Дайте нам знать в комментариях ниже.

1000) выделенных документов или несколько раз запускаем макрос для обработки небольшого количества документов, может переполниться память. Зависают приложения. Приходится перезагружать компьютер.
В макросе после работы с очередным объектом выполняю
SET имя=Nothing.
Что Вы порекомендуете использовать в скрипте для очистки памяти?

Здравствуйте. Ох уж эта память. Сложно рекомендовать, так как рекомендации иногда понимаются неправильно, потом получается только хуже :(.

А большой скрипт? Оптимизировать и ускорить можно значительно. Щас темку кину по оптимизации (ну это по скорости). Нужно простой примерчик который вызывает проблемы, мы попробуем показать как его можно оптимизировать.

И еще по памяти. Часто бывает что это в TechnologiCS проблема, при обычной работе вы этого не заметите, а при использовании в АПИ многие вещи вылезти могут. Так что тут не всегда оптимизация поможет. И нужно на каждой версии смотреть.

Да получил. Посмотрим, точную версию TechnologiCS скажите пожалуйста.

TCS 5.0.2.0(9328)
Спасибо за примеры оптимизации

Ну в вашем случае все просто.

Объекты, которые создаются от Application как правило глобальные, и создаются один раз на весь сеанс работы программы. Таким образом мы можем безопасно писать такой код

так как в течении всей работы объект TCSApp.DocParams будет один и тот же.

тоже самое относится и к строке (которая у вас выполняется в цикле)


Set DOC_module=TCSApp.SingleDoc( CSDN_ … sInteger)

Это объект полученный от Application, и он тоже создается один раз (но один раз для каждого документа). При интенсивной работе это может вызвать проблемы с памятью.

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

IModule2.UniqueUserModuleName Получить уникальное значение для UserModuleName

IOcs_Application2.DeleteModuleByUserModuleName Удалить модуль по пользовательскому уникальному имени

IOcs_Application2.ModuleByUserModuleName Получить модуль по пользовательскому уникальному имени

Таким образом, с помощью данных методов мы можем управлять временем жизни нужны нам объектов (НО!! не надо пользоваться этим повсеместно, могут быть другие побочные эффекты, которые вместо контроля над объектами дадут серьезные проблемы)

Если ваш код переписать вот к таком виду

вы будете уничтожать созданные вами объекты.
Или еще лучше вот к такому виду, чтобы еще меньше сделать вероятность влияния ошибки ( поскольку UniqueUserModuleName создаст уникальное имя, которое никому не будет известно).

надеюсь это поможет.

Спасибо!
Добавила к каждому
SET имя= объект
предложенные методы.

НО!! не надо пользоваться этим повсеместно, могут быть другие побочные эффекты, которые вместо контроля над объектами дадут серьезные проблемы

Хочу уточнить, во избежание побочных эффектов, где этого делать не следует?

И ещё надо ли использовать в данном случае SET имя=Nothing?

По желанию. Скриптовый движок сам отлично отслеживает все ссылки, так что особого смысла в таком коде нет, кроме может красоты. Бывает правда необходимо уничтожить объект в определенном месте программы, или просто ссылку убить дабы исключить последующее использование, тогда конечно требуется подобный код. Или скажем после вот такого кода

обращение к DOC_module после вызова DeleteModuleByUserModuleName вызовет ошибку, так как DOC_module в скрипте существует и валиден, а внутренний объект TechnologiCS уже уничтожен. В этом случае сброс DOC_module может быть и полезен, хотя система все равно отслеживает это.

не надо пользоваться этим повсеместно

скажем так. Как я говорил выше, объекты, которые создаются от Application как правило глобальные, и создаются один раз на весь сеанс работы программы. Остальные объекты, полученные через Properties, ChildModules и пр. уничтожаются автоматически, и никаких дополнительных действий с ними не требуется. Если же начать пользоваться приведенными выше функциями, то наоборот мы получим кучу глобальных объектов, да еще и с уникальным именем, до которых потом вы уже вряд ли достучитесь, а автоматически они уже не уничтожатся.

Вообще смысл вышеприведенных методов не столько для того, чтобы делать удаление, а для того чтобы можно было создавать свои собственные глобальные настройки и хранить их между запусками скриптов. Способы применения зависят от конкретных задач.
Пример. Запускается скрипт, который просит пользователя сделать кучу настроек, или выбрать что либо. Затем пользователь запускает другой скрипт, которому тоже нужны эти же самые настройки. Мы можем через глобальные объекты создать (или запомнить уже существующий) некий нужный нам модуль и на старте скрипта попытаться найти его, если не нашли, то запустить выбор/создание настроек.

Поэтому и рекомендации по использованию дать сложно, но главное не считать DeleteModuleByUserModuleName панацеей от проблем с памятью и усложнять код постоянными его вызовами.

Читайте также: