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

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

19.02.2015, 22:55. Показов 3254. Ответов 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
8488 / 6155 / 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
8488 / 6155 / 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
8488 / 6155 / 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
8488 / 6155 / 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
8488 / 6155 / 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
8488 / 6155 / 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
Ответ Создать тему
Новые блоги и статьи
Настройка записи справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru