.NET

.NET

Reply
Valued Mentor
AubelecBE
Posts: 387
Registered: ‎01-27-2010
Message 1 of 7 (242 Views)

How to Force GC to clear memory after à BindXRef

242 Views, 6 Replies
01-14-2013 04:16 AM

Hi all, i have a issu when i use BindXRef.

I have 4 XREF in my dwg.  so i use à Do / While for each XREF i have found.
It work fine but whrn the Xref is big File, i have the issue "Out Of memory".

So the question : How i can Force the GC to clear all memory not used.

My Think is to force the GC to Clear the memory before to use BindXRef() with only one XRef before to BindXRef with another.


Sorry for my english.

Here my code  :



Dim LockDoc As DocumentLock = doc.LockDocument
                Dim MemNumBoucle As Integer = -1

                Dim CollXRef As New ObjectIdCollection
                Do
                    CollXRef.Clear()
                    Dim xg As XrefGraph = db.GetHostDwgXrefGraph(True)
                    Dim root As GraphNode = xg.RootNode

                    Using tr As Transaction = db.TransactionManager.StartTransaction
                        For o = 0 To root.NumOut - 1 Step 1
                            Dim child As XrefGraphNode = CType(root.Out(o), XrefGraphNode)
                            If child.XrefStatus = XrefStatus.Resolved Then
                                Dim bl As BlockTableRecord = tr.GetObject(child.BlockTableRecordId, OpenMode.ForRead)

                                'i_ed.WriteMessage(vbCrLf & i_indent + child.Database.Filename)

                                ' Name of the Xref (found name)

                                ' You can find the original path too:
                                If bl.IsFromExternalReference = True Then
                                    GestionAUTOCAD.EcrireSurLigneDeCommande(vbCrLf & "Xref path name: " + bl.PathName)
                                    CollXRef.Add(bl.ObjectId)
                                    'détection si le liage a été fait :
                                    If MemNumBoucle <> root.NumOut Then
                                        MemNumBoucle = root.NumOut
                                        Exit For
                                    End If


                                End If
                            End If
                        Next

                        'trouvé un xref --> Adding

                        If CollXRef.Count > 0 Then
                            Try
                                doc.Database.BindXrefs(CollXRef, False)
                            Catch ex As Exception
                                okErr = True
                                MsgBox("Erreur lors de la liaison d'un Xref" & vbCrLf & "--> Essayer de lier le premier niveau", _
                                              vbOKOnly & vbCritical, _
                                              "Erreur Système")
                            Finally
                                tr.Commit()
                            End Try
                        End If
                    End Using
                    GestionAUTOCAD.EcrireSurLigneDeCommande(vbCrLf & "-> " & CollXRef.Count.ToString)
                Loop Until (CollXRef.Count = 0) Or (okErr = True)

 PS : the var MemNumBoucle is used for detection of XRef Not binding if this XRef is used in another XREf : Here a example :

- DWG

-- XREF : R+1

-- XREF : ARCHI

-------------- XREF R+1

 

In this example i cant BindXREf ('R+1') alone. I need to BindXRef('ARCHI') before

 

 

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 2 of 7 (236 Views)

Re: How to Force GC to clear memory after à BindXRef

01-14-2013 04:44 AM in reply to: AubelecBE

Binding XRefs doesn't require a lot of memory by the CLR.

 

It's AutoCAD that's using the memory, not the CLR, so there's nothing you can do with the GC to fix that.

 

The only solution would be to bind one XRef at a time, save the drawing to a temporary file, exit AutoCAD completely, restart it, open the temp file, and bind another xref.

 

 

Valued Mentor
AubelecBE
Posts: 387
Registered: ‎01-27-2010
Message 3 of 7 (210 Views)

Re: How to Force GC to clear memory after à BindXRef

01-14-2013 02:34 PM in reply to: DiningPhilosopher

but why when i bind xref manually one by one i have no problem ?

 

 

ADN Support Specialist
Balaji_Ram
Posts: 694
Registered: ‎03-21-2011
Message 4 of 7 (178 Views)

Re: How to Force GC to clear memory after à BindXRef

01-22-2013 08:24 AM in reply to: AubelecBE

Hello,

 

Here are few suggestions that you may try :

 

1) Call the Database.DisableUndoRecording with true as its parameter before the binding and restore it again after your task is done. This can help in reducing the memory usage.

 

2) Try creating another custom command for binding a single xref and then call it repeatedly for binding all the xrefs.

 

I havent tried these but I hope it helps in reducing the memory usage. If you can share the non-confidential drawings to reproduce the error, I can see if there are any other ways to make it work.



Balaji
Developer Technical Services
Autodesk Developer Network

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 5 of 7 (160 Views)

Re: How to Force GC to clear memory after à BindXRef

01-23-2013 05:33 AM in reply to: AubelecBE

If you only see the problem when you're automating the process, then it could be an issue with your code, but that's just a wild guess.

Valued Mentor
AubelecBE
Posts: 387
Registered: ‎01-27-2010
Message 6 of 7 (137 Views)

Re: How to Force GC to clear memory after à BindXRef

01-24-2013 04:44 AM in reply to: DiningPhilosopher

thank i have to try the diabled option.

 

I have issue when i bind manually all the file.
in same time but no problem when i bind manualy one by one.

 

 

Valued Mentor
AubelecBE
Posts: 387
Registered: ‎01-27-2010
Message 7 of 7 (116 Views)

Re: How to Force GC to clear memory after à BindXRef

02-01-2013 04:14 AM in reply to: Balaji_Ram

so i finaly tryed your db.DisableUndoRecording


i crash autocad.  but manyally i cant bindxref all the 5 xref. it work only one by one.

 

if created a do while for bind xref one by one. :

Dim LockDoc As DocumentLock = doc.LockDocument
                db.DisableUndoRecording(True)
                Dim OkPasserAuSuivant As Boolean
                Dim MemNumRoot As Integer = -1
                Dim MemNumIndex As Integer = -1

                Dim CollXRef As New ObjectIdCollection
                Do
                    CollXRef.Clear()
                    OkPasserAuSuivant = False
                    Dim xg As XrefGraph = db.GetHostDwgXrefGraph(True)
                    Dim root As GraphNode = xg.RootNode
                    'vérification de la limitation !
                    If root.NumOut > 6 Then
                        MsgBox("Il y a plus que 3 Xrefs à lier !" & vbCrLf & _
                               "Ce programme ne peut en lier que 2 d'affilés car AUTOCAD risque" & vbCrLf & _
                               "de planter à cause de l'utilisation abusive de la mémoire" & vbCrLf & _
                               "Vous en avez actuellement : " & root.NumOut.ToString & vbCrLf & _
                               "Veuillez lier les XRef manuellement un à un et relancer ce programme.", _
                               MsgBoxStyle.Information, "Limitation atteinte")
                        okErr = True
                        Exit Do
                    End If

                    Dim BoucleEnCours As Integer
                    'mém Num de XRef
                    If root.NumOut = 0 Then Exit Do

                    If MemNumRoot <> root.NumOut Then
                        BoucleEnCours = 0
                        MemNumIndex = BoucleEnCours
                        MemNumRoot = root.NumOut

                    Else
                        BoucleEnCours = MemNumIndex + 1
                        MemNumIndex = MemNumIndex + 1
                        If BoucleEnCours >= root.NumOut Then Exit Do
                    End If


                    Dim child As XrefGraphNode = CType(root.Out(BoucleEnCours), XrefGraphNode)
                    If child.XrefStatus = XrefStatus.Resolved Then
                        Using tr As Transaction = db.TransactionManager.StartTransaction
                            Dim bl As BlockTableRecord = tr.GetObject(child.BlockTableRecordId, OpenMode.ForRead)

                            If bl.IsFromExternalReference = True Then
                                GestionAUTOCAD.EcrireSurLigneDeCommande(vbCrLf & "Xref en cours : " + bl.PathName & vbCrLf, True)
                                CollXRef.Add(bl.ObjectId)
                            Else
                                OkPasserAuSuivant = True
                            End If

                            tr.Commit()
                        End Using
                    End If
                    'Next

                    'trouvé un xref --> Liage

                    If CollXRef.Count > 0 Then
                        Using tr As Transaction = db.TransactionManager.StartTransaction

                            Try
                                doc.Database.BindXrefs(CollXRef, False)
                            Catch ex As Exception
                                okErr = True
                                MsgBox("Erreur lors de la liaison d'un Xref" & vbCrLf & "--> Essayer de lier le premier niveau", _
                                              vbOKOnly & vbCritical, _
                                              "Erreur Système")
                            Finally
                                tr.Commit()
                            End Try
                        End Using
                    End If
                    'End Using
                Loop Until ((CollXRef.Count = 0) And (OkPasserAuSuivant = False)) Or (okErr = True)

                db.DisableUndoRecording(False)

                LockDoc.Dispose()
                LockDoc = Nothing

 now i try to repeatly call my DLL for bing only one xref and i have to add a timer in each bind...

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.