Поиск:

Ответ в темуСоздание новой темы Создание опроса
> C++ Builder разница между проектами, VCL и Console 
:(
    Опции темы
bsa
Дата 24.6.2008, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: нет
Всего: 196



Цитата(Riply @ 24.6.2008,  21:50)
Пока нет доказательств, будем считать ее спорной smile
Редко можно встретить женщину-программиста (женщину-программиста вообще сложно встретить) с подобной дотошностью...
Ну что ж, вперед - доказывай или опровергай.

Цитата(Riply @ 24.6.2008,  21:50)
Ну это кому как. Я привыкла убирать за собой и не вижу в этом неудобств.
Да и плюсом считаю возможность чистить тогда, когда мне надо,
а не когда соизволит компилятор smile 
Есть способы форсировать "чистку" (например, reserve(0) у вектора). С другой стороны, у тебя в голове много лишнего места, чтобы хранить информацию о том, что где-то что-то надо освободить?
PM   Вверх
Riply
Дата 24.6.2008, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: нет
Всего: 32



Цитата(bsa @  24.6.2008,  22:06 Найти цитируемый пост)
Ну что ж, вперед - доказывай или опровергай.


Попробую. О результатах будет доложено smile

Раз уж пошло такое дело, еще вопрос:
Под VS 2005, вроде, мне удается более-менее контролировать утечки памяти с помощью _Crt функций.
А вот из под Builder`а не получается до них добраться. Они в нем вообще есть ?
Если нет, то как можно контролировать в нем утечки памяти ?

PM MAIL   Вверх
bsa
Дата 24.6.2008, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: нет
Всего: 196



Цитата(Riply @ 24.6.2008,  22:46)
Если нет, то как можно контролировать в нем утечки памяти ?

во, во...
CodeGuard тебе в помощь. Активируешь его, запускаешь прогу, и у тебя вылазиет полный список ошибок работы с памятью.
PM   Вверх
Riply
Дата 25.6.2008, 01:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: нет
Всего: 32



Цитата(Riply @  24.6.2008,  22:46 Найти цитируемый пост)
Попробую. О результатах будет доложено 


Какие-то странные результаты. 
Имеем код:
Код

void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
  void *pTmp = NULL;
  int i = 0;
  int aCount = 1000000;
  ULONG BytesPerBlock = 1024;
  _LARGE_INTEGER Tm1, Tm2, gFrequency;
  __int64 Elapsed;
    
  if (QueryPerformanceFrequency(&gFrequency))
   {
     QueryPerformanceCounter(&Tm1);
     for (i = 0; i != aCount; ++i)
      {
         pTmp =  malloc(BytesPerBlock);
         free(pTmp);
       }
     QueryPerformanceCounter(&Tm2);
     Elapsed = (((Tm2.QuadPart - Tm1.QuadPart) * 1000000) / gFrequency.QuadPart);
     ShowMessage("malloc/free:  " + IntToStr(Elapsed));

     QueryPerformanceCounter(&Tm1);
     for (i = 0; i != aCount; ++i)
      {
        pTmp =  new char [BytesPerBlock];
        delete [] pTmp;
       }
     QueryPerformanceCounter(&Tm2);
     Elapsed = (((Tm2.QuadPart - Tm1.QuadPart) * 1000000) / gFrequency.QuadPart);
     ShowMessage("new/delete:  " + IntToStr(Elapsed));

     if (IsMemoryManagerSet)
       {
          TMemoryManagerEx MemMgr;
          GetMemoryManager(MemMgr);
          QueryPerformanceCounter(&Tm1);
          for (i = 0; i != aCount; ++i)
    {
      pTmp =  MemMgr.GetMem(BytesPerBlock);
      MemMgr.FreeMem(pTmp);
     }
          QueryPerformanceCounter(&Tm2);
          Elapsed = (((Tm2.QuadPart - Tm1.QuadPart) * 1000000) / gFrequency.QuadPart);
          ShowMessage("MemoryManagerEx:  " + IntToStr(Elapsed));
        }
  };
}


Получаем такие сообщения:
malloc/free:               203854
new/delete:              268167
MemoryManagerEx:  160868

Либо я чего-то не понимаю, либо где-то партачу,
либо Борландовский менеджер опять на коне smile

Добавлено через 1 минуту и 56 секунд
Цитата(Riply @  25.6.2008,  01:01 Найти цитируемый пост)
Имеем код:

Как-то код неправильно отформатировался. Sorry.

PM MAIL   Вверх
bsa
Дата 26.6.2008, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: нет
Всего: 196



видимо его специально оптимизировали.
PM   Вверх
Riply
Дата 2.7.2008, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: нет
Всего: 32



Цитата(bsa @  26.6.2008,  21:13 Найти цитируемый пост)
видимо его специально оптимизировали. 


Может кому будет интересно:
Один мой знакомый заинтересовался механизмом работы с памятью и быстродействием.
Вот что он пишет:
"..............
В результате исследований выяснилось, что занимает больше памяти совсем не 
строки, вопреки моим ожиданиям, а некоторые структуры. Переупорядочил поля 
тех структур - получил в одном случае более 10% экономии, другие проверить 
не могу пока, но думаю там сэкономлено больше. Надеюсь дадут ещё время на 
это, есть ещё как и более глубокие идеи оптимизации, так и идеи насчёт 
улучшения средства исследования (которое пока то ли работает то ли не 
работает - об этом ниже).

Детоуринг RtlAllocateHeap/RtlReAllocateHeap/RtlFreeHeap - идея правильная. 
C++овский new  сводится к сишонму malloc, оттуда вызывается HeapAlloc, 
оттуда уже RtlAllocateHeap. Внутри кое-каких майкрософтовских библиотек 
вызываются Heap* функции напрямую, всё равно попадаем туда же. WinAPI 
функции типа CreateWindow вызывают функции вроде LocalAlloc или HeapAlloc, 
всё равно идём в RtlAllocateHeap. Разумеется, не факт что malloc и 
GlobalAlloc будут _всегда_ сводится к RtlAllocateHeap, но похоже что в моём 
случае все существенные объёмы проходят через RtlAllocateHeap.

Detours заинтересовала как она работает. Например, т.к. задача перехвата 
этим путём может быть разной сложности и в общем случае не решаема (функцию 
чисто из ret так не перехватишь), интересно как далеко она ушла в обработке 
сложных ситуаций. Также интересно насколько транзакция detours действительно 
транзакция. И если настолько, насколько я надеюсь, то как оно работает.

Спуск по коллстеку через StackWalk или StackWalk64 - не всегда работает. На 
самом деле перед этой функцией стоит тоже в общем случае не решаемая задача. 
Реально получается интересный факт - с winapi до ехе спускается вседа, но со 
спуском из кода CRT до прикладного кода иногда проблемы. У StackWalk есть 
параметр ContextRecord. Глянь что про него в MSDN пишут. Оказывается, что 
если передать туда эту структуру, то StackWalk в состоянии обработать спуск 
с malloc до new, иначе - нет. Причём, заполнение структуры не влияет. Видимо 
влияет то заполнение, которое делается самой StackWalk в предыущих вызовах. 
Пока что самые существенные объёмы уже успешно обрабатываются, но будет 
время - попытаюсь добиться чтобы всё обрабатывалось.

Анализ - прост как валенок. Начиная с начала профилируемого интервала при 
Alloc запоминаем в hash_map указатель как ключ, размер и стек вызовов в виде 
адресов возврата как значение. при Free удаляем. В конце профилируемого 
интервала для каждого оставшегося в hash_map адреса ищем адрес возврата 
своего кода: получаем файл исходников из адреса возрата, и функцией strstr 
проверяем его на принадлежность своему коду. Из всего этого составляем 
другой hash_map, здесь уже ключ - адрес_возврата_в_свой_код, значение - 
сумма выделенной памяти ( /* интересная тонкость STL: */ std::map<int,int> 
m; m[3] += 2; m[3] += 2; /* чему равно теперь m[3] ? думаешь неизвестно ? а 
вот и нет, оно будет равно 4. */ ). Теперь перекладываем содержимое этого 
мэпа в контейнер, соритрованый по получившемуся там размеру (я взял map), 
дополняем результат файлом и срокой и именем метода из адреса своего кода - 
вот и результат. Конечно, это не будет "максимально полная картина". Но уже 
представления что надо оптимизировать, а что нет - даёт.

Теперь почему это "то ли работает то ли не работает". Разумеется мы должны 
защититься от повторного вхождения в перехваченные функции, кроме того т.к. 
хешмэпы не потокобезопасны, их нужно защитить. Казалось бы - критическая 
секция, а потом флаг уже вошли мы в перехваченую функцию или нет, если уже 
вошли - выходим. Но это приводит к дедлоку, т.к. Sym* и StackWalk выделяют 
что-то в другом потоке. Сейчас работает хитрая система из TLS и крит. 
секций, но я не уверен, что там всё ок.
.........."

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0694 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.