Author Topic: VBA: Problems of memory  (Read 3300 times)

0 Members and 1 Guest are viewing this topic.

Eduardo Crespo

  • Guest
VBA: Problems of memory
« on: May 29, 2006, 12:12:54 PM »
Introduction:
Hello, I am writing a set of macros to deal with AutoCAD archives (Planes) to add drawing objects to them (Lines and others) in order to make calculations on them (Depending on the geometric characteristics of the lines, the position of them in the drawing, etc.). To make this project, I have been using VBA and I didn't use any system based on databases to maintain the data, I only used methods to enclose and recover extended data to the drawing entities (SetXData and GetXData methods.) and SelectionSet objects to recover the processed entities later and their attached data.
The problem:
The macros that I wrote goes on, but whenever I execute them I see in the task's administrator (Windows 2000) how the memory used by acad.exe grows more and more, and finally after many executions the system closes AutoCAD because this. I don't know what causes the increase of memory used by AutoCAD, but the reason isn't the use of extended data: If after "processing" a drawing I close it and  immediately after I come back to the same drawing, the level of memory used by AutoCAD becomes the same as the beginning. Within the procedures in VBA I delete all the SelectionSet which have been created in the procedure before leaving it, and I don't use "dynamic" global variables. And also I use arrays, but all of them are local variables which are destroyed (Erase instruction) before the ending of the procedures. In summary, I haven't solved the memory problems.
The question:
Can anybody help me? Any answer will be welcome because I don't have any idea! (Any answer, It doesn't matter silly answers. ) I have spent many days solving this problem, I don't have time and the code is too large (More than 30000 lines) to try another way to develop my project. In addition, I'm not and expert, I have been working only with basic concepts in two dimensions (For one year, but I have few knowledge of AutoCAD, I have been working with VBA only.). Thanks in advance, and sorry for my English (I live in Spain. ).

Dnereb

  • Guest
Re: VBA: Problems of memory
« Reply #1 on: May 29, 2006, 01:29:13 PM »
Most of the time this has to do with memory leakage

You should adjust your macro's to prevent this as much as possible by:

Declaring your variables.
closing objects that can be closed or Quit if that appropriate and availeble. (My_Excel for instance)
close depending objects first
And set them to nothing by the same hierarchy.
Example

    Dim Eng As DAO.DBEngine
    Dim Db As DAO.Database
    Dim Rc As DAO.Recordset
   
    Set Eng = New DAO.DBEngine
    Set db = Eng.OpenDatabase ....
    '....
    '....
    '....
    Set Rc = db.OpenRecordset.....
    '....
    '....
    '....
    Rc.Close
    Db.Close
   
    Set Rc = Nothing 'depending on Db so set to nothing first
    Set Db = Nothing 'depending on Eng so set to nothing first
    Set Eng = Nothing

Bryco

  • Water Moccasin
  • Posts: 1883
Re: VBA: Problems of memory
« Reply #2 on: May 29, 2006, 01:43:21 PM »
There is an interesting discussion at autodesk http://discussion.autodesk.com/thread.jspa?messageID=5135697
and a function  http://www.freevbcode.com/code/FreeMemory.bas  was mentioned.
If you do a bit of debug.printing with this function, you can see where your memory usage jumps.
I am not quite sure what you mean by Erase instruction. I think erase has a bad wrap but I'm not sure.
"Erase recovers no memory for fixed-size arrays"

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: VBA: Problems of memory
« Reply #3 on: May 29, 2006, 01:59:59 PM »
For AutoCAD there is memory issues anyway, just open a drawing and work away (don't minimize the screen) then after a while the memory usage increases. You can check it in the Task Manager. Then when you minimize AutoCAD and maximize again, the mwmory usage is reduced back to a more managable level.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Bob Wahr

  • Guest
Re: VBA: Problems of memory
« Reply #4 on: May 30, 2006, 10:55:23 AM »
A possibility that hasn't been mentioned is your selection sets.  If you are making a new selection set every time it runs, you will end up with as many selection sets in memory as time that you have run it.  Large selection sets  could cause problems quickly.  It's hard to guess without knowing what you are doing though.

Eduardo Crespo

  • Guest
Re: VBA: Problems of memory
« Reply #5 on: May 31, 2006, 05:52:40 AM »
Thank you very much to all for your replies.

Dnereb, I will try to set all the SelectionSet to nothing before the ending of the procedures (I believe that the only variables which can be the responsible of the leak of memory are SelectionSet variables. ). I didn't do it, I thought that It was enough to clear and delete this variables. I usually wrote
Code: [Select]
    ....
    ....
    On Error Resume Next
    objAcSelSet1.Clear
    objAcSelSet1.Delete
    On Error GoTo 0
   
End Sub
at the ending of procedures which uses SelectionSet variables. As all this variables were declared as local variables, I thought that VB releases the memory of this variables after the procedures, but perhaps the memory is not released. I will write in this forum again if it works.

Bryco thanks a lot for your reference to the discussion of autodesk forum. I read it and it gave me some ideas to solve the problem (Such as try to delete selection sets from the SelectionSets collection, the use of the function of memory to debug, etc. ). About the use of Erase statement: In my code I use some arrays of drawing entities, dynamic arrays (Example: Dim objAcEntArrVigas() As AutoCAD.AcadEntity) of one dimension, which are used to point to the elements of a selection set first, and then to sort the elements into array in a way that the order of the elements in the array is the same that some order of the entities pointed by the array in the drawing (I use this to make calculations of distances between sorted entities in the drawing later. ). As the array is a dynamic array, I use the Erase statement to release the memory used by the array before, and then I use ReDim to assign a new size of memory to the array:
Code: [Select]
    ....
    ....
    Dim objAcEntArrVigas() As AutoCAD.AcadEntity
    ....
    ....
    Erase objAcEntArrVigas
    ReDim objAcEntArrVigas(0 To lng1)
    ....
    ....
    Erase objAcEntArrVigas
   
End Sub
For a fixed-size array Erase only clear the array, It don't recover memory as you say, but I only use Erase with the dynamic arrays.

Keith and Bob thanks, about the selection sets in the routine where I have the problem (Is a routine to calculate forces and moments over the structural elements of the plane, like moments and forces over beams, etc. ) inside the procedure which has the max level of depth I have 4 selection sets, I think that there aren't many selection sets, and the number of elements of each set is less than 1000 (Perhaps sometimes one of this sets can reach this number of elements. ). I usually write:
Code: [Select]
Private Sub PlanoActualizar(blnPlanta As Boolean, intPlanta As Integer, blnReCalculables As Boolean _
, blnContinuar As Boolean, udtError As mdlUtilidades01.tError)
   
    ' DECLARACIONES:
    Dim objAcSelSet1 As AutoCAD.AcadSelectionSet
    ....
    ....
    ....
   
    ' INSTRUCCIONES:
    blnContinuar = True
    blnError = False
    Call ErrorAnular(udtError)
   
    ' Línea de errores no controlados.
    ' Line of not-controlled errors.
    On Error GoTo linError0
   
    ' At the beginning of procedures I inicialize the SelectionSet variables.
    ' If I need to use a SelectionSet inside For....Next, I clear It in each loop, I don't create it again.
    str1 = "PlanoActualizarAcSelSet1"
    Set objAcSelSet1 = ThisDrawing.SelectionSets.Add(str1)
    objAcSelSet1.Clear
   
    If blnContinuar Then
        ....
        ....
        ....
    End If
   
' Línea de errores no controlados.
' Line of not-controlled errors.
linError0:
   
    If (Err <> 0) Then
        Call ErrorRetornar(Err, udtError)
        Resume linError0
    End If
   
    On Error GoTo 0
   
    On Error Resume Next
    ' Clears the set of his items.
    objAcSelSet1.Clear
    ' Delete the set.
    objAcSelSet1.Delete
    On Error GoTo 0
   
End Sub
After the execution of the routine all the selection sets which were created by the routines are deleted from the drawing, but the memory is not released. In some procedures I pass selection sets by reference, but these selection sets are destroyed when the execution comes back to the procedure where are declared.

Well, I will continue solving it... Many thanks (And sorry for my poor English. ).