Тема: Высвобождение памяти в VBA

Моя программа управляет перемещением объектов. При этом AutoCAD 2000 съедает много памяти, которая возвращается системе только после закрытия приложения.
Что делать?

Re: Высвобождение памяти в VBA

Кто-нибудь ответьте пожалуйста. Погибаю!
Дело в том, что при многократном выполнении команды Move AutoCad забирает у системы много памяти. При завершении моего VBA приложения память не высвобождается. Я многое пробовал, но радикального решения этой проблемы я не нашёл.
С уважением Александр Гадалов.

Re: Высвобождение памяти в VBA

Я в прошлом году парился с такой же проблемой. 4-5 раз запускаешь VBA макрос потом вываливалось сообщение, что виртуальной памяти хана и всед за ним вываливался LDD.
Я в цикле пытался перебрать точки поверхности, т.к. такая коллекция вполне доступна и по For Each должна перебираться, но если в поверхности более 10000 точек (а это не много) то цикл даже до конца не успевал отработать!!!
Так я эту фигню и не победил. Причем оперативки у меня стоит 1 Гб !!! Щас тружусь над написанием собстенной ActiveX DLL, в которой, как мне пока кажеца, этих проблем не должно быть, т.к. каждую объектную переменную в конце её жизни нада явно прибивать. А этого в автодеске наверна не принято.

Кстати Иван Образцов еще пол года назад обещал разобраться, но увы, видимо это неизлечимо...

Re: Высвобождение памяти в VBA

В Excel такой же еффект. Первый раз макрос на VBA отрабатывает довольно быстро. А далее с каждым новым запуском работает заметно медленнее. Правда система ни разу не висла. Я не спец в программировани, но подозреваю, что при прямом обращении к обектам (минуя переменные) выделяется память. Чем больше обектов, тем больше памяти на них уходит. Возможно, при повторном прямом обращении к тому же объекту выделяется еще память. Сбросить память можно только для переменных. Отсюда может быть верен вывод: если есть проблема с памятью, то к максимальному количеству объектов желательно обращаться только через переменные. Для большого количества объектов должна происходить постоянная перезапись разных объектов в одну и ту же соответствующую переменную. Вероятно при этом не будет расходоваться дополнительная память. А память отведенная под переменные может быть легко сброшена. Код конечно растянется но может быть это решение. Что скажете?

Re: Высвобождение памяти в VBA

2Брагин. ... не знаю, как в Excel, с ним у меня никогда небыло таких проблем, но в Land Desktop'е я это всё проходил. Разницы никакой. Я и переменные всякого разного типа пробовал и через COM в свой ActiveX exe-шник передавал (ActiveX exe работает в другом адресном пространстве), один фиг, разницы никакой. После чего я сделал вывод, что где бы ты ни рожал какой-нить объект из библиотеки LDD, память после его убивания не освобождается. Это говорит о том, что внутри COM модели неграмотно прописана функция Terminate, или что-нить типа того.
   Ведь если посмотреть на работу автокада со стороны ObjectARX, то могу заметить, к примеру, что при удалении любого Entity в базе данных (нажатием кнопки Delete), объект вовсе не удаляется, а помечается как удалённый и исчезает с модели (ну или с листа) а сама база dwg очищается от удалённых Entities'ов только при завершении работы сеанса автокада.
   Подозреваю, что аналогично ведут себя все автодесковские объекты.
   А мой сосед, ARX-писарь, говорит, что если переписать мои тулсы на ARX, будет то же самое, т.к. работать с объектами LDD сиравно придётся через COM-модель, т.к. LDDшной библиотеки для ARX'а нету.
   Короче я тихо надеюсь, что не прав, если кто-нить знает о чем я тут расписал, отзовитесь и наставьте на путь истинный...

Re: Высвобождение памяти в VBA

Позвольте кое-что уточнить. Давайте рассмотрим небольшой кусочек программы.
For I = 0 To 10
        appendObj.Move firstPoint, secondPoint
        appendObj.Update
Next I
В данном случае объект был создан  всего один раз, поэтому он не может съесть памяти больше , чем он уже съел. Однако при каждом его перемещении acad запрашивает дополнительные ресурсы памяти. Самое неприятное то, что при одинаковых действиях он запрашивает разные порции памяти. Я недавно начал работать в этой программе, но мне кажется, что при перемещении какого-либо объекта acad создаёт и расширяет массив базовых точек для каждого объекта с целью построения вектора перемещения. Что же касается разного объёма запрашиваемой памяти, то я думаю, что это связано с опережением запроса на выделение нового блока, с целью повысить скорость выполнения данной операции.
Я попытался всякий раз вызывать API функции GetProcessHeaps и HeapCompact для высвобождения неиспользуемых куч, однако и это не помогло. Видимо acad не перезаписывает этот массив. Если я не прав - поправьте меня. Если же прав, тогда позвольте задать вопрос: для чего acad хранит всю историю преобразований объектов?
P.S.  Возможно для реализации команды UNDO, однако UNDOCTL=0 не помогает. Можно конечно подключиться к процессу и попробовать получить адреса массивов с целью их перезаписи, но не зная броду не лезу в воду.

Re: Высвобождение памяти в VBA

2Саша ... Память при перемещении растёт и без VBA. Попробуй открыть Task Manager и посмотри на память. Потом подвигай объекты в самом акаде и сравни память. Она должна подрасти. Для чего - хз... так устроены мозги акада...
В твоём случае память может захламиться только если выполнить очень много перемещений, порядка нескольких тысяч, мобыть и сотен тысяч (Это от объекта зависит).

ЗЫ: Если в автокаде ничего не создавать  а только перемещать объекты, то рано или поздно он распухнет и "умрет"...

Re: Высвобождение памяти в VBA

Александр, осмелюсь только лишь пояснить свою мысль упрямого дилетанта. Что если Ваш пример переписать так:
For I = 0 To 10
set appendObj=...
appendObj.Move firstPoint, secondPoint
appendObj.Update
appendObj=Nothing
Next I
К сожалению мои макросы не тянут на эту проверку.  А то я бы попробовал.
С уважением, Брагин.

Re: Высвобождение памяти в VBA

... хороший пример неэффективного кода ... wink