AD>Подскажите в чем плюсы и минусы?
если коротко и не вдаваясь в дебри то Стек
1. Очень быстро.
2. Не нужно заботиться о разрушении
3. Не рекомендуется размещать большие объекты. Размещение очень больших невозможно Куча
1. Значительно медленнее
2. НУЖНО заботиться о разрушении самостоятельно
3. Можно выделять объекты такого размера, какого позволяет память(ОС)
AD>Спасибо.
Re: создавать объект в куче или стеке?
От:
Аноним
Дата:
21.08.07 05:31
Оценка:
Здравствуйте, Alex Dav, Вы писали:
AD>Подскажите в чем плюсы и минусы?
А, что обязательно должны быть плюсы и минусы?
Это просто 2 разных способа.
Скажем объекты, созданные на стеке уничтожаются автоматически
при выходе из блока. Это плюс или минус?
Вопрос в такой поставновке просто не имеет смысла.
Это примерно как просить объяснить преимущества и недостатки яблок перед грушами.
и еще добавлю, что из того что не нужно заботиться о разрушении или нужно следует время жизни — в случае кучи, время жизни произвольно, в случе стека -выход за пределы блока.
Здравствуйте, dip_2000, Вы писали:
_>и еще добавлю, что из того что не нужно заботиться о разрушении или нужно следует время жизни — в случае кучи, время жизни произвольно, в случе стека -выход за пределы блока.
со временем жизни понятно, спасибо. А за счет в стеке создание быстрее? А обращение (по скорости) различается?
Здравствуйте, Аноним, Вы писали:
А>А, что обязательно должны быть плюсы и минусы? А>Это просто 2 разных способа.
Вот потому то и должны быть — это не просто два способа, а два принципиально разных
А>Вопрос в такой поставновке просто не имеет смысла.
А в какой? У меня есть объект где его лучше разместить? (так лучше? )))
Re[4]: создавать объект в куче или стеке?
От:
Аноним
Дата:
21.08.07 06:19
Оценка:
Здравствуйте, Alex Dav, Вы писали:
AD>Здравствуйте, dip_2000, Вы писали:
_>>и еще добавлю, что из того что не нужно заботиться о разрушении или нужно следует время жизни — в случае кучи, время жизни произвольно, в случе стека -выход за пределы блока.
AD>А за счет в стеке создание быстрее?
память выделяется несколькими ассемлерными инструкциями против вызова/вызовов системных ф-ций AD>А обращение (по скорости) различается?
в общем случае нет
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alex Dav, Вы писали:
AD>>Здравствуйте, dip_2000, Вы писали:
_>>>и еще добавлю, что из того что не нужно заботиться о разрушении или нужно следует время жизни — в случае кучи, время жизни произвольно, в случе стека -выход за пределы блока.
AD>>А за счет в стеке создание быстрее? А>память выделяется несколькими ассемлерными инструкциями против вызова/вызовов системных ф-ций AD>>А обращение (по скорости) различается? А>в общем случае нет
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alex Dav, Вы писали:
AD>>Здравствуйте, dip_2000, Вы писали:
_>>>и еще добавлю, что из того что не нужно заботиться о разрушении или нужно следует время жизни — в случае кучи, время жизни произвольно, в случе стека -выход за пределы блока.
AD>>А за счет в стеке создание быстрее? А>память выделяется несколькими ассемлерными инструкциями против вызова/вызовов системных ф-ций
Глупость полная.
Работа на стеке осуществляется быстрее, потому что при инициализации процесса сразу выделяется две страницы памяти, после чего при заполнении страницы данными (при подходе к границе) выделяется следующая. Т.е. один раз выделена, много раз используется. При работе с кучей память выделяется под то количество, которое запрашивается (+ техническая информация о блоке памяти) — при этом осуществляется поиск свободного места в текущей памяти.
Re[3]: создавать объект в куче или стеке?
От:
Аноним
Дата:
21.08.07 06:47
Оценка:
Здравствуйте, Alex Dav, Вы писали:
А>>Вопрос в такой поставновке просто не имеет смысла. AD>А в какой? У меня есть объект где его лучше разместить? (так лучше? )))
Ну можно спросить об особенностях того или иного способа.
А "плюсы" и "минусы" предполагают, что есть ущербность.
Кстати, совсем не уверен, что в стандрате С++ вообще что-то говорится о стеке и куче.
А говорится там о "Automatic storage duration" и "Dynamic storage duration".
Т.е. используются некие абстракции, которые задают разные способы управлением временем жизни объектов.
Никаких тебе стеков и кучей. Что в общем-то правильно.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alex Dav, Вы писали:
А>>>Вопрос в такой поставновке просто не имеет смысла. AD>>А в какой? У меня есть объект где его лучше разместить? (так лучше? )))
А>Ну можно спросить об особенностях того или иного способа. А>А "плюсы" и "минусы" предполагают, что есть ущербность.
Возможно именно это я и имел ввиду ))
Здравствуйте, Uzumaki Naruto, Вы писали:
UN>Глупость полная.
UN>Работа на стеке осуществляется быстрее, потому что при инициализации процесса сразу выделяется две страницы памяти, после чего при заполнении страницы данными (при подходе к границе) выделяется следующая. Т.е. один раз выделена, много раз используется. При работе с кучей память выделяется под то количество, которое запрашивается (+ техническая информация о блоке памяти) — при этом осуществляется поиск свободного места в текущей памяти.
Чего-то ты тут намешал всё вместе. Виртуальная память что для стека, что для кучи выделяется примерно одинаково: вначале резервируется адресное пространство, по мере обращений, если по каким-то адресам отсутствует физическая страница памяти, она тут же выделяется операционной системой.
Но приложение работает с памятью на другом уровне. Для всех переменных в стеке память выделяется одной ассемблерной командой sub esp,<размер>. Про кучу ты уже написал. Правда реальные пацаны чаще мспользуют аллокаторы и пулы объектов, чтоб не вызывать каждый раз тормозные new и malloc.
Здравствуйте, remark, Вы писали:
R>Здравствуйте, Alex Dav, Вы писали:
AD>>У меня есть объект где его лучше разместить?
R>В рамочку и на стену
А после моего возвращения он все еще будет висеть? А не получу я утечку части стены?
R>Размещать по-умолчанию на стеке, пока не требуется другого.
> Для всех переменных в стеке память выделяется одной ассемблерной командой sub esp,<размер>.
sub esp ничего не выделяет, а просто вычитает из esp размер, т.е. сдвигается по уже зарезервированному при инициализации потока стеку... Читайте батенька Рихтера... глава 16.
Здравствуйте, Uzumaki Naruto, Вы писали:
>> Для всех переменных в стеке память выделяется одной ассемблерной командой sub esp,<размер>.
UN>sub esp ничего не выделяет, а просто вычитает из esp размер, т.е. сдвигается по уже зарезервированному при инициализации потока стеку...
В таком случае и выделение из кучи тоже "ничего не выделяет". Т.к. виртуальная память для кучи тоже зарезервирована при инициализации процесса.
UN>Читайте батенька Рихтера... глава 16.
Рихтера я 10 лет назад читал. Наизусть каждую главу учить как-то не счёл нужным.
Здравствуйте, Uzumaki Naruto, Вы писали:
AD>>>А за счет в стеке создание быстрее? А>>память выделяется несколькими ассемлерными инструкциями против вызова/вызовов системных ф-ций
UN>Глупость полная.
Неполная, ибо...
UN>Работа на стеке осуществляется быстрее, потому что при инициализации процесса сразу выделяется две страницы памяти, после чего при заполнении страницы данными (при подходе к границе) выделяется следующая.
Это ты рассказываешь, как сделано в больших виндах. Не забудь про кучу платформ, где механика другая.
UN> Т.е. один раз выделена, много раз используется. При работе с кучей память выделяется под то количество, которое запрашивается (+ техническая информация о блоке памяти) — при этом осуществляется поиск свободного места в текущей памяти.
Менеджер кучи тоже не дурак. Если ты занял блок, и это повлекло занятие новой страницы, а потом освободил его, — то менеджер не обязан немедленно освобождать страницу...
Кстати говоря, и со стеком та же история.
Но в целом, картина получается такая:
— выделение памяти на стеке — это простейшее арифметическое действие, и к тому же не требует синхронизации
— выделение памяти в куче — всегда более затейливо, а если куча не lock-free, то ещё и синхронизировано (добавляем накладные расходы на работу с мьютексом и, потенциально, ожидание в нём)
Здравствуйте, Uzumaki Naruto, Вы писали:
>> Для всех переменных в стеке память выделяется одной ассемблерной командой sub esp,<размер>.
UN>sub esp ничего не выделяет, а просто вычитает из esp размер, т.е. сдвигается по уже зарезервированному при инициализации потока стеку... Читайте батенька Рихтера... глава 16.
Если так рассуждать, то и malloc — это тоже обычно просто какая перетасовка указателей, а не вовсе не выделение памяти.
Согласен с machine3000, что вы тут без особой надобности мешаете вместе разноуровневые понятия.
> Но в целом, картина получается такая: > — выделение памяти на стеке — это простейшее арифметическое действие, и к тому же не требует синхронизации
Маленькое уточнение — иногда это цикл. Например, если под виндой за раз выделяется более одной страницы. Что впрочем ситуации с дешевизной выделения не меняет.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Alex Dav, Вы писали:
AD>Подскажите в чем плюсы и минусы?
Плюсы и минусы — в розетке. Да и там они меняются местами 50 раз в секунду.
Всё зависит от твоих потребностей.
Если тебе нужно время жизни объекта произвольное — то куча, без альтернатив.
Если объекты полиморфные — опять куча. В очень редких случаях можно похимичить с placement new на стеке.
Если объекты большие, и особенно, если функция рекурсивная — снова куча. Чтобы не исчерпать стек.
Если же время жизни "автоматическое" (от входа до выхода из выражения, из блока, из функции), тип известен во время компиляции, и размер небольшой — добро пожаловать на стек.
Здравствуйте, alzt, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
AD>>>А обращение (по скорости) различается? А>>в общем случае нет
A>На мой взгляд у переменных в стеке больше шансов попасть в кеш, следовательно скорость должна быть быстрее.
Может шансов и больше, но скорость, в моем случае, одинаковая. Я проверял.
Когда вы двигаетесь по стеку ничего не выделяется и всегда есть шанс уйти не туда, куда надо... Работа со стеком осуществляется командами push & pop и регистром esp (для x86 платформы) — не морочьте людям голову. Работа со страницами стека осущствляется функциями ядра, точно так же как и с обычной кучей, только механизм другой и часть памяти под стек выделяется при инициализации процесса.
Re[10]: создавать объект в куче или стеке?
От:
Аноним
Дата:
21.08.07 20:53
Оценка:
UN>Когда вы двигаетесь по стеку ничего не выделяется и всегда есть шанс уйти не туда, куда надо... Работа со стеком осуществляется командами push & pop и регистром esp (для x86 платформы) — не морочьте людям голову.
Вообщето так оно и есть. Адресное пространство под стек резервируется единожды при создании потока, и комититься в пределах 1мб по мере необходимости. Освобождение же памяти происходит единожды — при убивании потока (это если конечно самому не освободить себе стек). Стек это нефрагментируемый участок памяти, который резервируется один раз, растет в пределах зарещервированного размера (обычно 1мб), и освобождается при смерти потока.
Создание объекта на стеке это:
sub esp, sizeof(object)
//probe страниц на запись если размер объекта вылазит за размер страницы памяти
mov ecx, esp //а вот и this
call [ecx+constructor_offset]
При этом ядро здесь _может_ дергаться _неявно_ если при обращении память под стек текущего стека начинает нехватать и ядро отращивает потоку стек ловя PAGE_GUARD исключения. Никаких системных вызовов при этом user-mode коду делаьт вообще не нужно.
Убивание объекта на стеке это соответственно:
call [ecx+destructor_offset]
add esp, sizeof(object)
Тут ядро вообще никак не беспокоиться.
Рост стека _может_ происходить только при первом вызове foo();
Создание на куче это обход дерева менеджера кучи процесса, поиск подходяшщего нода-описателя свободного участка памяти, запрос ОС выделить память если таковой не найден, реорганизация структур менеджера кучи.
А я о чем говорю =) Так я и говорю, только я смотрю со сотроны ядра, а они со сотроны процесса — но все равно такты тратятся — так или иначе =)
Re[12]: создавать объект в куче или стеке?
От:
Аноним
Дата:
21.08.07 23:27
Оценка:
А в многопоточном такой же механизм старниц этих, как и однопоточном?
И еще вот вопрос: Если объкт создался в стёке, когда я его тестил, его можно смело создавать в стёке в потоках?
Здравствуйте, Аноним, Вы писали:
А>А в многопоточном такой же механизм старниц этих, как и однопоточном?
Да.
А>И еще вот вопрос: Если объкт создался в стёке, когда я его тестил, его можно смело создавать в стёке в потоках?
Да. У каждого потока свой стек, проблемы могут возникнуть при межпотоковом взаимодействии и при обращении к статическим переменным (общим для всех потоков).
На мой взгляд у переменных в стеке больше шансов попасть в кеш, следовательно скорость должна быть быстрее.
Пётр Седов (ушёл с RSDN)
Re[14]: создавать объект в куче или стеке?
От:
Аноним
Дата:
24.08.07 01:45
Оценка:
Здравствуйте, Uzumaki Naruto, Вы писали:
UN>Да. У каждого потока свой стек, проблемы могут возникнуть при межпотоковом взаимодействии и при обращении к статическим переменным (общим для всех потоков).