фрагментация оперативной памяти?

Автор Тема: фрагментация оперативной памяти?  (Прочитано 8468 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
Добрый день коллеги.
Есть вот такая замечательная функция (упрощенная для наглядности)
работает как надо, но при больших объемах данных (например есть чертеж с ~8000 линий) , начинает жрать РАМ. причем потом не отпускает эго.
У меня тут косяк какой то или ОС злая и фрагментирует память так что потом отпустить не может?
нашел такую ссылку, нзн связано ли.
https://adndevblog.typepad.com/autocad/2012/07/problem-with-autocads-memory-usage.html

Возможно функцию можно как то опримизировать чтобы не перебирать всё подряд?
Назначение функции перебрать все пересечения линий, и вставить блок с маской в точке пересечения

Код - C++ [Выбрать]
  1. inline void addCrossingsAfterExplodeTest(AcDbObjectIdArray modified)
  2.         {
  3.                 AcDbObjectIdArray idArray;
  4.  
  5.                 for (int i = 0; i < modified.length(); i++)
  6.                 {
  7.                         if (getType(modified[i]) != PIPE_TYPE)
  8.                                 continue;
  9.                         if (!idArray.contains(modified[i]))
  10.                                 idArray.append(modified[i]);
  11.                 }
  12.  
  13.                 for (int i = 0; i < idArray.length(); i++)
  14.                 {
  15.                         for (int j = i; j < idArray.length(); j++)
  16.                         {
  17.  
  18.                                 AcGePoint3dArray crossPoints;
  19.                                 AcDbObjectId tstId = idArray[j];
  20.                                 if (idArray[i] == tstId)
  21.                                         continue;
  22.  
  23.                                 AcDbObjectPointer<AcDbLine> lin1(tstId, AcDb::kForRead);
  24.                                 AcDbObjectPointer<AcDbLine> lin2(idArray[i], AcDb::kForRead);
  25.                                 if (lin1.openStatus() != Acad::eOk || lin2.openStatus() != Acad::eOk)
  26.                                         continue;
  27.  
  28.                                 if (lin1->intersectWith(lin2, AcDb::kOnBothOperands, crossPoints) != Acad::eOk)
  29.                                         continue;
  30.  
  31.                                 CString lr1 = lin1->layer();
  32.                                 CString lr2 = lin2->layer();
  33.  
  34.                                 AcGePoint3d l1s = lin1->startPoint();
  35.                                 AcGePoint3d l1e = lin1->endPoint();
  36.  
  37.                                 AcGePoint3d l2s = lin2->startPoint();
  38.                                 AcGePoint3d l2e = lin2->endPoint();
  39.  
  40.                                 lin1->close();
  41.                                 lin2->close();                 
  42.                         }              
  43.                 }
  44.         }
  45.  

пробовал этот код на Autocad 2016 и 2018 64-бит Eng, Win10

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: фрагментация оперативной памяти?
« Ответ #1 : 03-02-2020, 10:12:53 »
1. Создавай idArray сразу с таким физическим размером, как modified.
2. Вместо
Код - C++ [Выбрать]
  1. for (int j = i; j < idArray.length(); j++)
должно быть
Код - C++ [Выбрать]
  1. for (int j = i+1; j < idArray.length(); j++)
3. Это должно быть во врешнем цикле, а не во внутреннем
Код - C++ [Выбрать]
  1. AcDbObjectPointer<AcDbLine> lin2(idArray[i], AcDb::kForRead);
4. Это вообще не нужно, так как указатели интеллектуальные и они закроются сами:
Код - C++ [Выбрать]
  1. lin1->close();
  2. lin2->close();
Возможно функцию можно как то опримизировать чтобы не перебирать всё подряд?
Например, использовать RTree. Но в данном случае на объём памяти не повлияет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
Re: фрагментация оперативной памяти?
« Ответ #2 : 03-02-2020, 11:44:30 »
поменял
Код - C++ [Выбрать]
  1. CString lr1 = lin1->layer();
  2. CString lr2 = lin2->layer();
  3.  
на
Код - C++ [Выбрать]
  1. ACHAR * lr1 = lin1->layer();
  2. ACHAR * lr2 = lin2->layer();
  3.  
  4. delete lr1;
  5. delete lr2;
  6.  
RAM остается стабильным...

как то неожидал..

Отмечено как Решение begiz 03-02-2020, 13:27:01

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: фрагментация оперативной памяти?
« Ответ #3 : 03-02-2020, 11:55:29 »
RAM остается стабильным...
А вот тут интересный момент. Метод layer() возвращает строку ACHAR *, которую потом нужно освободить, о чем написано в документации. Но простое присвоение указателя ACHAR * строке CString не производит освобождения памяти строки. Так что тут всё очевидно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн begizАвтор темы

  • ADN Club
  • ***
  • Сообщений: 161
  • Карма: 8
  • Skype: begiz_i
Re: фрагментация оперативной памяти?
« Ответ #4 : 03-02-2020, 13:26:56 »
вот это я попал
и почему я решил что CString на себя возмет управление памятью...

Оффлайн pucher

  • ADN OPEN
  • Сообщений: 27
  • Карма: 0
Re: фрагментация оперативной памяти?
« Ответ #5 : 11-05-2024, 20:25:17 »
А вот тут интересный момент. Метод layer() возвращает строку ACHAR *, которую потом нужно освободить, о чем написано в документации.
Можно источник, где написано о необходимости явного освобождения памяти? В описании метода такого не вижу https://help.autodesk.com/view/OARXMAC/2023/ENU/?guid=OARXMAC-RefGuide-AcDbEntity__layer_AcString___const

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: фрагментация оперативной памяти?
« Ответ #6 : 11-05-2024, 21:18:38 »
pucher,
Источник вот: https://help.autodesk.com/view/OARXMAC/2023/ENU/?guid=OARXMAC-RefGuide-AcDbEntity__layer_const (хотя не факт, что следует использовать документацию для MAC. Правильнее: https://help.autodesk.com/view/OARX/2025/ENU/?guid=OARX-RefGuide-AcDbEntity__layer_const)
Есть два метода layer(). В тексте выше везде шла речь о методе, который возвращает ACHAR *, а не AcString (через ссылку), как в URL, который ты дал.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение