Author Topic: GenerateSectionGeometry how can dispose the memory ?  (Read 4266 times)

0 Members and 1 Guest are viewing this topic.

bikelink

  • Guest
GenerateSectionGeometry how can dispose the memory ?
« on: March 25, 2010, 10:49:15 AM »
Hi. just another question about the memory . it seems never released...
the memory increases  very quickly!! any suggest ?


if you run this loop very long autocad crash!
for (int k = 0; k < 1000; k++)   :pissed:
                        {
                            using (Transaction tr = d.Database.TransactionManager.StartTransaction())
                            {
                                Point3dCollection ptsez = new Point3dCollection();
                                ptsez.Add(p1);
                                ptsez.Add(p2);

                                //
                                 Autodesk.AutoCAD.DatabaseServices.Section se = new Section(ptsez, asseverticale);
                                ptsez.Dispose();
                                ptsez = null;
                               
                                se.TopPlane = limiteSup;
                                se.BottomPlane = limiteInf;
                                se.State = SectionState.Plane;

                                Array pIntFillEnts;
                                Array pBackgroundEnts;
                                Array pForegroundEnts;
                                Array pFurveTangencyEnts;
                                Array pCurveTangencyEnts;
                                using (Solid3d solido = tr.GetObject(idsolido, OpenMode.ForRead) as Solid3d)
                                {
                                       se.GenerateSectionGeometry(solido, out pIntFillEnts, out pBackgroundEnts, out pForegroundEnts, out pFurveTangencyEnts, out pCurveTangencyEnts);

                                }
                                se.Dispose();
                                se = null;
                                foreach (Entity e in pIntFillEnts)
                                        e.Dispose();
                                    foreach (Entity e in pBackgroundEnts)
                                        e.Dispose();
                                    foreach (Entity e in pForegroundEnts)
                                        e.Dispose();
                                    foreach (Entity e in pFurveTangencyEnts)
                                        e.Dispose();
                                    foreach (Entity e in pCurveTangencyEnts)
                                        e.Dispose();
                                tr.Commit();
                            }
                            System.Diagnostics.Debug.WriteLine(GC.GetTotalMemory(false));
                            System.Diagnostics.Debug.WriteLine(k);
                        }

dann.boy.001

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #1 on: March 25, 2010, 11:35:05 AM »
Hello

I think you need to move this

'Start transaction
using (Transaction tr = d.Database.TransactionManager.StartTransaction())

'End transaction
tr.Commit();

outside loop

for (int k = 0; k < 1000; k++)

Like this:


                            using (Transaction tr = d.Database.TransactionManager.StartTransaction())

for (int k = 0; k < 1000; k++)   
                        {
                            {
                                Point3dCollection ptsez = new Point3dCollection();
                                ptsez.Add(p1);
                                ptsez.Add(p2);

                                //
                                 Autodesk.AutoCAD.DatabaseServices.Section se = new Section(ptsez, asseverticale);
                                ptsez.Dispose();
                                ptsez = null;
                               
                                se.TopPlane = limiteSup;
                                se.BottomPlane = limiteInf;
                                se.State = SectionState.Plane;

                                Array pIntFillEnts;
                                Array pBackgroundEnts;
                                Array pForegroundEnts;
                                Array pFurveTangencyEnts;
                                Array pCurveTangencyEnts;
                                using (Solid3d solido = tr.GetObject(idsolido, OpenMode.ForRead) as Solid3d)
                                {
                                       se.GenerateSectionGeometry(solido, out pIntFillEnts, out pBackgroundEnts, out pForegroundEnts, out pFurveTangencyEnts, out pCurveTangencyEnts);

                                }
                                se.Dispose();
                                se = null;
                                foreach (Entity e in pIntFillEnts)
                                        e.Dispose();
                                    foreach (Entity e in pBackgroundEnts)
                                        e.Dispose();
                                    foreach (Entity e in pForegroundEnts)
                                        e.Dispose();
                                    foreach (Entity e in pFurveTangencyEnts)
                                        e.Dispose();
                                    foreach (Entity e in pCurveTangencyEnts)
                                        e.Dispose();
                            }

                            System.Diagnostics.Debug.WriteLine(GC.GetTotalMemory(false));
                            System.Diagnostics.Debug.WriteLine(k);
                        }

                                tr.Commit();


Danijel

bikelink

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #2 on: March 25, 2010, 11:45:37 AM »
transaction it's INSIDE the loop.(k++) (every LOOP starts and ends a transaction)   in scope about using transaction


 for (int k = 0; k < 100000; k++)
                        {
                           using (Transaction tr = d.Database.TransactionManager.StartTransaction())
                            {
                                Point3dCollection ptsez = new Point3dCollection();
                                ptsez.Add(p1);
                                ptsez.Add(p2);

                                // creazione linea sezione
                                //BlockTable bt = (BlockTable)tr.GetObject(d.Database.BlockTableId, OpenMode.ForRead);
                                //BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);


                                Autodesk.AutoCAD.DatabaseServices.Section se = new Section(ptsez, asseverticale);
                                ptsez.Dispose();
                                ptsez = null;
                                
                                se.TopPlane = limiteSup;
                                se.BottomPlane = limiteInf;
                                se.State = SectionState.Plane;

                                Array pIntFillEnts;
                                Array pBackgroundEnts;
                                Array pForegroundEnts;
                                Array pFurveTangencyEnts;
                                Array pCurveTangencyEnts;
                                using (Solid3d solido = tr.GetObject(idsolido, OpenMode.ForRead) as Solid3d)
                                {
                                       se.GenerateSectionGeometry(solido, out pIntFillEnts, out pBackgroundEnts, out pForegroundEnts, out pFurveTangencyEnts, out pCurveTangencyEnts);

                                }
                                
                                se.Dispose();
                                se = null;

                                foreach (Entity e in pIntFillEnts)
                                        e.Dispose();
                                    foreach (Entity e in pBackgroundEnts)
                                        e.Dispose();
                                    foreach (Entity e in pForegroundEnts)
                                        e.Dispose();
                                    foreach (Entity e in pFurveTangencyEnts)
                                        e.Dispose();
                                    foreach (Entity e in pCurveTangencyEnts)
                                        e.Dispose();

                                    tr.Commit();
                            }
                            // THIS INCREASES..!!  :pissed: :pissed: :pissed: :pissed:
                            System.Diagnostics.Debug.WriteLine(GC.GetTotalMemory(false));
                            System.Diagnostics.Debug.WriteLine(k);

                        }
« Last Edit: March 25, 2010, 12:00:29 PM by bikelink »

Glenn R

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #3 on: March 25, 2010, 06:55:17 PM »
Why are you calling Dispose explicitly? There are VERY few occasions where you need to do this and I suspect it's one of the causes of your recent posts about problems.

dann.boy.001

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #4 on: March 26, 2010, 08:56:21 AM »

You don't need to open transaction in every loop,
it is enough to open before and after iterating,
because it slow down autocad...

Danijel

Glenn R

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #5 on: March 26, 2010, 09:01:58 AM »

You don't need to open transaction in every loop,
it is enough to open before and after iterating,
because it slow down autocad...

Danijel

Agreed.

bikelink

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #6 on: March 26, 2010, 09:54:04 AM »

You don't need to open transaction in every loop,
it is enough to open before and after iterating,
because it slow down autocad...

Danijel

Agreed.

ok ok but is not the problem! the problem is a memory leak..

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8858
  • AKA Daniel
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #7 on: March 26, 2010, 10:07:45 AM »
Since you like to play with memory, you should switch to ARX  :laugh:

bikelink

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #8 on: March 26, 2010, 11:05:13 AM »
also in ARX it's the same! the section "generateSectionGeometry"  also used with acdbAcisDeleteModelerBulletins don't restore the memory.
try a loop and wait a crash...

this is arx..



ACED_ARXCOMMAND_ENTRY_AUTO(CSectionPlaneApp, AsdkSectionPlane, _CreaSez, CreaSez, ACRX_CMD_TRANSPARENT, NULL)

static void AsdkSectionPlane_CreaSez(void)
{
// Get two points in the plane
ads_point pnt;
int iTest = acedGetPoint(NULL,_T("\nSelect first point of the line in the plane: "),pnt);
if(iTest != RTNORM)
return;

AcGePoint3d startPnt(pnt[X],pnt[Y],pnt[Z]);
// transform the selected point to wcs
AcGeMatrix3d ucsMat;
startPnt.transformBy(ucsMat);
AcGePoint3dArray sectVertices;
sectVertices.append(startPnt);
AcGePoint3d endPnt;
iTest = acedGetPoint(pnt,_T("\nSelect second point of the line in the plane: "),asDblArray(endPnt));
if(iTest != RTNORM)
return;
// transform the selected point to wcs
endPnt.transformBy(ucsMat);
sectVertices.append(endPnt);

Acad::ErrorStatus es;
ads_name name;
ads_point pt;
acedEntSel(_T("\nSeleziona solido"), name, pt);
AcDbObjectId objId;
acdbGetObjectId(objId, name);
// AcDbObject * pObj;

//AcDbObjectId sectionId = pSection->objectId();

AcGeVector3d vv;
vv = sectVertices[1]-sectVertices[0];
for (int kkk=0;kkk<10000;kkk++)
{
AcDbSection* pSection = new AcDbSection(sectVertices, AcGeVector3d::kZAxis);
if(pSection==NULL)
return;
if(Acad::eOk != (pSection->setState(AcDbSection::kPlane)))
return;
/*AcDbObjectId sectionId = AcDbObjectId::kNull;
sectionId = CSectionPlaneUtility::AddEntityToDatabase(pSection);
if(sectionId == AcDbObjectId::kNull)
return;*/
AcString sectName = _T("FirstSection");
if(Acad::eOk != (pSection->setName(sectName)))
return;
if(Acad::eOk != (pSection->setIndicatorTransparency(90)))
return;
if(Acad::eOk != (pSection->setHeight(AcDbSection::kHeightAboveSectionLine, 3.0)))
return;
if(Acad::eOk != (pSection->setHeight(AcDbSection::kHeightBelowSectionLine, 1.0)))
return;
/*if(Acad::eOk != (pSection->enableLiveSection(true)))
return;*/

AcArray boundaryList, fillList, backgroundList, foregroundList, tangentList;
//AcDbEntity *pEnt = NULL;

/*for (int i = 0; i < solidIds.length(); i++)
{*/
AcArray boundarySet, fillSet, backgroundSet;
AcArray foregroundSet, tangentSet;

AcDbEntity *pEnt = NULL;
AcArray entList;
// es = acdbOpenObject(pEnt, solidIds, AcDb::kForRead);
es = acdbOpenObject(pEnt, objId, AcDb::kForRead);

if (es == eOk)
{
es = pSection->generateSectionGeometry(pEnt,
boundarySet, fillSet, backgroundSet,
foregroundSet, tangentSet);
pEnt->close();

entList.append(boundarySet);
entList.append(fillSet);
entList.append(backgroundSet);
entList.append(foregroundSet);
entList.append(tangentSet);
}
//}


pSection->close();
pSection=NULL;
}
}


here i found peoples with similar problems
http://www.caduser.ru/forum/index.php?PAGE_NAME=read&FID=24&TID=29706&MID=169545&phrase_id=235951#message169545

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8858
  • AKA Daniel
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #9 on: March 26, 2010, 11:20:13 AM »
what are you going to do with the contents of entList? 

bikelink

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #10 on: March 26, 2010, 11:53:23 AM »
i'm going to set this to check similar ents with other sections.. but that's now is a simple test.
when entList going out of scope his destructor is called to delete every *void.. isn't it ?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8858
  • AKA Daniel
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #11 on: March 26, 2010, 12:57:33 PM »
no not with an array of pointers, you would need to iterate and delete non database resident entities,
regardless the routine sure does chew up lots of memory  and I don't know how to free it  :mrgreen:
.. here is my test code

Code: [Select]
static void SectionPlane_doit(void)
  {
    // Get two points in the plane
    AcGePoint3dArray sectVertices;
    ads_point ads_pnt_a = {0.0,0.0,0.0};
    ads_point ads_pnt_b = {0.0,0.0,0.0};
    AcGeMatrix3d ucsMat = AcGeMatrix3d::kIdentity;

    int iTest = acedGetPoint(NULL,_T("\nSelect first point of the line in the plane: "),ads_pnt_a);
    if(iTest != RTNORM)
      return;

    iTest = acedGetPoint(ads_pnt_a,_T("\nSelect second point of the line in the plane: "),ads_pnt_b);
    if(iTest != RTNORM)
      return;

    // transform the selected point to wcs
    AcGePoint3d startPnt = asPnt3d(ads_pnt_a);
    AcGePoint3d endPnt = asPnt3d(ads_pnt_b);
    startPnt.transformBy(ucsMat);
    endPnt.transformBy(ucsMat);
    sectVertices.append(startPnt);
    sectVertices.append(endPnt);

    ads_name name = {0L,0L};
    ads_point pt = {0.0,0.0,0.0};
    iTest = acedEntSel(_T("\nSeleziona solido"), name, pt);
    if(iTest != RTNORM)
      return;

    AcDbObjectId objId;
    acdbGetObjectId(objId, name);
    AcGeVector3d vv;
    vv = sectVertices[1]-sectVertices[0];
    const AcString sectName = _T("FirstSection");

    for (int kkk=0;kkk<10000;kkk++)
    {
      acdbAcisDeleteModelerBulletins();
      AcDbSection* pSection = new AcDbSection(sectVertices, AcGeVector3d::kZAxis);
      if(pSection==NULL)
        return;

      AcDbObjectPointer<AcDbSection> spSection;
      spSection.acquire(pSection);

      if(Acad::eOk != (spSection->setState(AcDbSection::kPlane)))
        return;
      if(Acad::eOk != (spSection->setName(sectName)))
        return;
      if(Acad::eOk != (spSection->setIndicatorTransparency(90)))
        return;
      if(Acad::eOk != (spSection->setHeight(AcDbSection::kHeightAboveSectionLine, 3.0)))
        return;
      if(Acad::eOk != (spSection->setHeight(AcDbSection::kHeightBelowSectionLine, 1.0)))
        return;

      AcArray<AcDbEntity*> boundarySet, fillSet, backgroundSet;
      AcArray<AcDbEntity*> foregroundSet, tangentSet;
      AcDbEntity *pEnt = NULL;

      if (acdbOpenObject(pEnt, objId, AcDb::kForRead) == eOk)
      {
        spSection->generateSectionGeometry(pEnt, boundarySet,
          fillSet, backgroundSet,
          foregroundSet, tangentSet);
        pEnt->close();

        cleaner(boundarySet);
        cleaner(fillSet);
        cleaner(backgroundSet);
        cleaner(foregroundSet);
        cleaner(tangentSet);
      }
    }
  }

  static void cleaner(AcArray<AcDbEntity*> &entList)
  {
    for(size_t idx = 0 ; idx < entList.length() ; idx++)
    {
      AcDbEntity *pTmp = entList[idx];
      delete pTmp;
    }
    entList.setLogicalLength(0);
  }


bikelink

  • Guest
Re: GenerateSectionGeometry how can dispose the memory ?
« Reply #12 on: March 29, 2010, 04:32:00 AM »
Ok! i'm going to test your suggest