Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182

Долгое высвобождение памяти

19.02.2015, 22:55. Показов 2993. Ответов 47
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Возможно, такой вопрос уже встречался, но ответа мне найти не удалось.
Намахал template List.
C++
1
2
3
4
5
6
7
8
9
10
~List(){
        Item *srh = (Item*)head, *dead;
        clock_t t1 = clock();
        while( srh ){
            dead = srh;
            srh = srh->next;
            delete (T*)dead; // используется наследование от Item. Удалить как class T.
        }
        plog("< %p: %p ms\n", this, clock()-t1 );
    };
100000 объектов T размера около 200b были созданы за 84 ms. Удалялся список 9937 ms.

Конечно, не так часто будут выделяться/освобождаться гигабайты памяти, но и, в случае необходимости, выгружать списки с данными из памяти по нескольку часов не будет радовать. Возможно как-то ускорить этот процесс и с чем связана такая длительность?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.02.2015, 22:55
Ответы с готовыми решениями:

Высвобождение динамической памяти
Нужна помощь, в проблеме высвобождения памяти, все делаю по стандартам С++, но постоянно выдает ошибки. Фото 1, в случае, если пытаюсь...

Корректное высвобождение памяти в list
У меня все нормально работает, ну и по логике тоже вроде нормально, но намучился с Коректным высвобождением памяти(ну пару раз упала...

Высвобождение памяти для 3 измерения массива
Здравствуйте. Не могу понять почему выходит ошибка. Я сделал 3х мерный массив, у которого 2 строки . Он неравномерный. В 1 строке 3...

47
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
19.02.2015, 23:32
Функция clock возвращает количество "тиков", а не миллисекунд, так
что данные вычисления неверны. А количество тиков в секунду определяется
константой CLOCKS_PER_SEC.

Добавлено через 16 минут
Кстати, на моем железе (Core i5-2500) полиморфное удаление миллиона
объектов из вектора (базовый класс - пустая структура с массивом на 200 байт и
виртуальным деструктором) занимает чуть меньше 200 миллисекунд.
0
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
19.02.2015, 23:41  [ТС]
Убежденный, ваше утверждение, что данные вычисления неверны, неверно. А за просветление спасибо (более верная запись plog("< %p: %f s\n", this, (clock()-t1)/CLOCKS_PER_SEC ).
C++
1
2
/* Clock ticks macro - ANSI version */
#define CLOCKS_PER_SEC  1000
Но проблема осталась.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
20.02.2015, 08:38
Eraston, Ваше утверждение, что мое утверждение, что данные вычисления неверны, неверно - неверно.


C++
1
2
3
4
5
6
7
8
#include <ctime>
#include <cstdio>
 
int main()
{
    printf("CLOCKS_PER_SEC = %li\r\n", CLOCKS_PER_SEC);
    return 0;
}
Visual C++
> CLOCKS_PER_SEC = 1000
GCC (Ideone, CodePad)
> CLOCKS_PER_SEC = 1000000
Цитата Сообщение от Eraston Посмотреть сообщение
Но проблема осталась.
Может быть, какой-то код в деструкторе занимает долгое время ?..
2
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
20.02.2015, 09:31
Eraston, а что ты хотел? У тебя списочная можель памяти
Цитата Сообщение от Eraston Посмотреть сообщение
srh = srh->next;
, её плюс - легко расширяется, минус - долго высвобождается. Ускорить высвобождение можно лишь одним путём, превдарительно создавай страйпы(алокнутые области памяти, в которых будешь уже расставлять поинтеры), со страйпами можешь очень приблизится ко времени освобождения памяти для цельного блока того же размера отводимого под массив.
И да в DEBUG-е есть песочница для процесса, там всё очень меделнно аллокается и деаллокается(скомпилируй релиз и запусти exe без студии, ну и замеряй время)

Добавлено через 3 минуты

Не по теме:

Цитата Сообщение от Убежденный Посмотреть сообщение
Может быть, какой-то код в деструкторе занимает долгое время ?..
- да список у него омг..

0
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
22.02.2015, 17:16  [ТС]

Не по теме:

Убежденный, Ваше утверждение, что мое утверждение, что ваше утверждение, что данные вычисления неверны, неверно - неверно, неверно, ибо данные вычисления относятся к конкретному случаю, а не являются общим случаем.



Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Eraston, а что ты хотел? У тебя списочная модель памяти
Та хоть деревянная, объекты в любом случае будут удаляться поочередно, а значит без разницы, как они связаны между собой и в чем, не? Исключением разве что может стать "блочная модель памяти":
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
страйпы
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
И да в DEBUG-е есть песочница для процесса, там всё очень меделнно аллокается и деаллокается(скомпилируй релиз и запусти exe без студии, ну и замеряй время)
Так точно! Скомпилил в дебаге, запустил exe. Создает 1млн*200б за 1359, освобождает за 421. Спасибо.

Не по теме:

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
да список у него омг..
Чего в нем "омг"?

0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
22.02.2015, 17:42

Не по теме:

Цитата Сообщение от Eraston Посмотреть сообщение
Чего в нем "омг"?
- потмоу что список не массив в деструкторе списка идёт проход по всем элементам и для каждого итема вызывается деструктор, после чего каждый освободившийся блок памяти поступает в распорядение менеджера памяти, котоырй индивидуально рабоатет с элементарным блоком ранее отводимым под итем списка(т.е N раз (где N число элементов списка) дёргается ряд внутренних функций менеджера памяти), в случае массива менеджер памяти отрабатывает всего 1 раз - он метит облать от начала массива до конца освобождённой(тут как минимум для списка сложность N). Разницу ощущаешь 1 раз и N раз, м?Короче я не собираюсь учить кагдого школьника на тему почему списочная память освобождается медленней. Сходи в школу.



Добавлено через 7 минут
https://ru.wikipedia.org/wiki/Менеджер_памяти
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.02.2015, 18:21
Цитата Сообщение от Eraston Посмотреть сообщение
Та хоть деревянная, объекты в любом случае будут удаляться поочередно, а значит без разницы, как они связаны между собой и в чем, не?
Не.

Массив освобождается сразу же целиком, например.

Операция освобождения ещё медленнее, чем операция выделения.
А ручки тянутся к операционной системе.

Можно 1 раз освободить весь блок целиком.
Можно 1000 раз освобождать кусочек за кусочком.

Можно 1 раз нарваться на медленную операцию.
Можно 1000 раз нарываться на медленную операцию.

А кроме того, очередь очереди рознь.

В обычном листе создаваемые объекты разрабрасываются по всей памяти как придется.
Например, один объект находится на одной странице памяти, а другой - на другой.

Системе приходится постоянно прыгать туда-сюда,
и то и дело подтягивая то одну страницу памяти, то другую.

То ли дело, если бы объекты находились в одном непрерывном куске памяти:
вероятность кэш-миссов была бы значительно меньше.

В общем, я хз, почему у вас так медленно освобождается память.
Я с такими проблемами не сталкивался.

Однако пулы памяти, которые используют оптимальные стратегии выделения и размещения объектов
по принципу "кэш-френдли" действительно имеют смысл.

Если у вас затык на работе с памятью,
то есть смысл рассмотреть вариант использования пулов памяти.

зы: на самом деле я почти уверен, что затык где-то в другом месте.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.02.2015, 19:14
http://www.cplusplus.com/refer... /?kw=clock

Добавлено через 8 минут
Цитата Сообщение от hoggy Посмотреть сообщение
зы: на самом деле я почти уверен, что затык где-то в другом месте.
Например в выборе "типа контейнера".
0
22.02.2015, 20:07

Не по теме:

Цитата Сообщение от Eraston Посмотреть сообщение
Убежденный, Ваше утверждение, что мое утверждение, что ваше утверждение, что данные вычисления неверны, неверно - неверно, неверно, ибо данные вычисления относятся к конкретному случаю, а не являются общим случаем.
Если ты знаешь больше нас - зачем задаёшь подобные вопросы?

0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.02.2015, 20:31
C++
1
delete (T*)dead; // используется наследование от Item. Удалить как class T.
Кстати что за ... ?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.02.2015, 20:48
Цитата Сообщение от Avazart Посмотреть сообщение
Например в выборе "типа контейнера".
У ТС самодельный мопед.

Цитата Сообщение от Avazart Посмотреть сообщение
Кстати что за ... ?
сишное приведение к наследнику, и удаление наследника.

может быть ТС просто не в курсе насчет виртуальных деструкторов.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.02.2015, 20:56
Цитата Сообщение от hoggy Посмотреть сообщение
У ТС самодельный мопед.
Какая разница? Я имел ввиду что возможно не стоит применять список.

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
может быть ТС просто не в курсе насчет виртуальных деструкторов.
Вероятно.
Хотя непонятно зачем тут "что-то виртуальное" если используешь шаблоны.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.02.2015, 21:00
Цитата Сообщение от Avazart Посмотреть сообщение
Хотя непонятно зачем тут "что-то виртуальное" если используешь шаблоны.
C++
1
// используется наследование от Item.
Так устроен ТС`овский мопэд: держит все элементы по указателю на Item*
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.02.2015, 21:06
А чего не void* сразу
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.02.2015, 21:37
Цитата Сообщение от Avazart Посмотреть сообщение
А чего не void* сразу
Вы зря смеетесь. Реально воид для этих целей многие контейнеры и используют.
Если по потрохам стандартных контейнеров полазить - там тоже можно что-то подобное найти.

А связанно это с тем, что в шаблоны стремятся выносить
лишь необходимый для типо-безопасности минимум.

А все остальное реализуют нешаблонные вспомогательные механизмы,
что позволяет свести к минимуму затраты на инстанцирование шаблонов,
и размер итогового кода.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.02.2015, 21:47
Цитата Сообщение от hoggy Посмотреть сообщение
Если по потрохам стандартных контейнеров полазить - там тоже можно что-то подобное найти.
Вот неплохо бы если вы конкретно указали "где".

Добавлено через 56 секунд
Цитата Сообщение от hoggy Посмотреть сообщение
А связанно это с тем, что в шаблоны стремятся выносить
лишь необходимый для типо-безопасности минимум.
Т.е выносить весь код, т.е максимум, а не минимум.

Добавлено через 3 минуты
Цитата Сообщение от hoggy Посмотреть сообщение
А все остальное реализуют нешаблонные вспомогательные механизмы,
что позволяет свести к минимуму затраты на инстанцирование шаблонов,
и размер итогового кода.
Вот интересно кто жертвует типобезопастностью для уменьшения времени компиляции и размера кода.

В любом случае это не в тему.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.02.2015, 22:21
Цитата Сообщение от Avazart Посмотреть сообщение
Вот неплохо бы если вы конкретно указали "где".
ну вот например, реализация от mingw в качестве ноды для листа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 struct _List_node_base
    {
      _List_node_base* _M_next;
      _List_node_base* _M_prev;
 
      static void
      swap(_List_node_base& __x, _List_node_base& __y) _GLIBCXX_USE_NOEXCEPT;
 
      void
      _M_transfer(_List_node_base* const __first,
          _List_node_base* const __last) _GLIBCXX_USE_NOEXCEPT;
 
      void
      _M_reverse() _GLIBCXX_USE_NOEXCEPT;
 
    // ещё куча всего
Не void*, но и не T*

Класс они использовали по видимому,
потому что им показалось удобным напихать туда всяких своих методов.

Хотел ещё глянуть msvc2013, но уж как то больно муторно.
Студия почему то не дает навигацию по своим потрохам.

Цитата Сообщение от Avazart Посмотреть сообщение
Т.е выносить весь код, т.е максимум, а не минимум.
Нет. Я сказал именно то, что хотел сказать: в шаблон только необходимый для типобезопасности минимум.
Остальное - не шаблонное вспомогательное.

Цитата Сообщение от Avazart Посмотреть сообщение
Вот интересно кто жертвует типобезопастностью для уменьшения времени компиляции и размера кода.
Никто. Нет никаких жертв.
Типобезопасность по прежнему обеспечивается времени компиляции.

Добавлено через 4 минуты
вот нода для std::map, так же не шаблонная:

C++
1
2
3
4
5
6
7
8
 struct _Rb_tree_node_base
  {
    typedef _Rb_tree_node_base* _Base_ptr;
    typedef const _Rb_tree_node_base* _Const_Base_ptr;
 
    _Rb_tree_color  _M_color;
 
   //ещё куча всего

В общем то, нечему удивляться. Ведь такие вещи делают люди грамотные.
Они не станут зазря плодить шаблонокод во все поля.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
22.02.2015, 22:54
MSVC2010

std::list
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        // TEMPLATE CLASS _List_nod
template<class _Ty,
    class _Alloc>
    class _List_nod
        : public _Container_base
    {   // base class for _List_val to hold storage
public:
    typedef typename _Alloc::template rebind<_Ty>::other _Alty;
    typedef typename _Alty::size_type size_type;
 
    struct _Node;
    typedef _Node *_Nodeptr;    // _Node allocator must have ordinary pointers
    typedef _Nodeptr& _Nodepref;
 
    struct _Node
        {   // list node
        _Nodeptr _Next; // successor node, or first element if head
        _Nodeptr _Prev; // predecessor node, or last element if head
        _Ty _Myval; // the stored value, unused if head
 
    private:
        _Node& operator=(const _Node&);
        };
Добавлено через 20 минут
std::map (xtree)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
        // TEMPLATE CLASS _Tree_nod
template<class _Traits>
    class _Tree_nod
        : public _Traits    // traits form ultimate base
    {   // base class for _Tree_ptr to hold storage
public:
    typedef typename _Traits::allocator_type allocator_type;
    typedef typename _Traits::key_compare key_compare;
    typedef typename _Traits::value_type value_type;
 
    typedef typename allocator_type::template rebind<value_type>::other
        _Alty;
    typedef typename _Alty::size_type size_type;
 
    struct _Node;
    typedef _Node *_Nodeptr;    // _Node allocator must have ordinary pointers
    typedef _Nodeptr& _Nodepref;
 
    struct _Node
        {   // tree node
        _Nodeptr _Left; // left subtree, or smallest element if head
        _Nodeptr _Parent;   // parent, or root of tree if head
        _Nodeptr _Right;    // right subtree, or largest element if head
        value_type _Myval;  // the stored value, unused if head
        char _Color;    // _Red or _Black, _Black if head
        char _Isnil;    // true only if head (also nil) node
 
    private:
        _Node& operator=(const _Node&);
        };
hoggy, Так что полагаю Вы вырвали из контекста код.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.02.2015, 23:05
Цитата Сообщение от Avazart Посмотреть сообщение
Так что полагаю Вы вырвали из контекста код.
я вырвал его из mingw482_32

А кроме того: не совсем понятно, зачем мелкомягкие запихали структуру в шаблон.

потому что по факту они используют её, как не шаблонную.

обратите внимание:

C++
1
2
3
4
5
6
7
8
9
10
11
12
struct _Node;
    typedef _Node *_Nodeptr;    // _Node allocator must have ordinary pointers
    typedef _Nodeptr& _Nodepref;
 
    struct _Node
        {   // tree node
        _Nodeptr _Left; // left subtree, or smallest element if head
        _Nodeptr _Parent;   // parent, or root of tree if head
        _Nodeptr _Right;    // right subtree, or largest element if head
        value_type _Myval;  // the stored value, unused if head
        char _Color;    // _Red or _Black, _Black if head
        char _Isnil;    // true only if head (also nil) node
так же, как и версии мингва, используется нешаблонная нода, которая ссылается сама на себя

с таким же успехом она могла бы быть вынесена наружу,
потому что не содержит зависимых от параметров шаблона типов.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.02.2015, 23:05
Помогаю со студенческими работами здесь

Очень долгое освобождение динамически выделенной памяти
Все никак не могу разобраться с одной проблеммой! У меня есть отображение, в котором хранятся указатели на абстрактный класс Node ...

Решение слишком долгое!
Добрый вечер всем, недавно начал изучать языки и многого не знаю. В целом разбираюсь неплохо, но не хватает практики. Написал программу...

Долгое завершение if (~1.500 мс)
Здравствуйте, в общем по какой-то причине операция if стала очень долго завершаться, все действия внутри себя выполняются очень быстро в...

Самое долгое слово в файле
Дали написать прогу: 1 Выводит из файла1 в файл2 строки где одно слово 2 Ищет во втором файле самое долгое слово 3 Считает количество...

Высвобождение памяти компонента
Добрый вечер, снова я. Не подскажите как организовать следующее: допустим я создаю динамический компонент при создании формы, скажем так: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru