![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
я не говорил, что это не нужно или плохо просто это - новый виток в бесконечной теме оптимизации ресурсов и производительности. Тут несколько типоков создать прийдется mr.DUDA, массив - это класс. Вот и все. Классы тоже " не копируется при присвоении, собирается при уборке" и элементами классов тоже могут быть не ссылочные типы. Точно так же, как элементами массива могут быть как ссылочные, так и типы по-значению. Я бы сказал, что массив - просто про-про-паттерн Это сообщение отредактировал(а) tol05 - 12.7.2007, 08:18 -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| ivashkanet |
|
||||||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Давайте и я своих 5 копеек...
Почему никто не вспоминает про такие операции как запаковка и распаковка? Именно таким образом значимые типы хранятся в куче. Т.е. у каждого Value-типа есть брат билзнец, который является ссылочным типом и храниться в куче. Все остальное мои мысли и не могут считаться полностью достоверными. Когда происходит эта распаковки и запаковка? А когда нужно что-то сделать со "значением", что не соответствует его типу, например:
По поводу массивов. Лопатил как-то MSDN и набрел на такую штуку:
Т.е. List<T> where T:ValueType пытается храниться в стеке до тех пор пока его не станут использовать как класс (вызывать его методы, например. Хотя, судя по цитате, при вызове методов не всегда происходит запаковка) либо до тех пор пока его не целесообразнее положить в кучу. Что-то похожее должно быть и про простой массив, но в MSDN я этого не нашел :(
ИМХО, пул и структуры вещи совершенно несовместимые. Ибо при присваивании структуры создается новая копия. Вот пул классов -- это да. |
||||||
|
|||||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Оффтопик. Но отвечу. Для того чтобы не копировало, юзается ref при передаче через аргументы метода. Во всех остальных случаях юзается через массив по индексу (т.е. без копирования в локальную переменную). Насчёт боксинга ты правильно заметил. Вот только вопрос про то почему стековая память называется такой, ею не являясь, остаётся открытым. -------------------- ![]() |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Тогда да, но что-то через одно место получается как-то. Ее же, ИМХО, никак нельзя использовать вне массива (ни для каких вычислений). Ну да ладно |
|||
|
||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
mr.DUDA, с чего ты взял, что
не мгу понять. Стековая память - это память, заполняемая при входе в функцию значениями и очищаемая после выхода из ф-ции. Она при входе в ф-цию заполнилась value-типами и ссылками на reference-типы. При выходе из ф-ции она очистилась - value-типы и ссылки на reference-типы уничтожились. Сами reference-типы еще остались в куче, до сборки мусора. Что не так? Массив - это класс. Члены массива хранятся в куче. Ссылка на массив хранится в стеке. -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Вообще запутал. Тут же себе противоречишь:
Получается, ссылка на массив уничтожится при выходе из функции, раз она "хранится в стеке". Хотя даже если и наоборот (ссылка - в куче, элементы - в стеке), всё равно не вкуриваю, где на самом деле хранятся элементы массива. 1. Если они не уничтожаются при выходе из метода - значит, вероятно не в стеке 2. Если они не боксятся и остаются нормальными value type (например int-ы), значит не в куче. Или всё-таки в куче можно хранить value-type объекты без боксинга? Или массивы - специальный тип, как я предполагаю? З.Ы ivashkanet, если интересно могу прислать образец кода. Кстати, мелкомягкие в XNA вовсю юзают структуры, а чтобы не копировалось лишний раз зря - повсеместно юзают модификатор ref. -------------------- ![]() |
|||
|
||||
| ivashkanet |
|
||||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
А что такое Стек, когда у нас есть только оперативная память? Конечно это обычная оперативная память, только она специально организована. И, ИМХО, выигрыш идет не на порядок, а раза в два-три (ИМХО), так как в случае стека мы вигрываем из-за отстутствия сборок мусора и более простому доступу (адреса переменных в стеке должы быть поменьше), но проигрываем из-за этой "организованности" стека. P.S. Про регистры и кэши процессора лучше не упоминать, так как процессы часто ожидают своей очереди у процессора, а в это время весь их контекст храниться в оперативке. P.P.S.
Почитай мой пост про List<T> where T:ValueType Добавлено через 14 минут и 49 секунд Не пасиб. Не нуна Не, все нормуль. Это нормальное поведение ссылочного типа: все ссылки на него теряются, а он все еще жив, но не долго -- до первой сборки мусора. Только вот, судя по MSDN, небольшиуе массивы хранятся в стеке |
||||
|
|||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
А хотя, пришли, плиз. Я хочу посмотреть. Только потрать немножко времени, выдели самое главное, пожайлуйста |
|||
|
||||
| tol05 |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
mr.DUDA, я видел, ты иногда бросаешь ссылки на книгу "C#2005 для профессионалов". Открой стр. 102
Я нигде не противоречил Массив - это класс. Члены массива хранятся в куче. Ссылка на массив хранится в стеке. Стековая память - это память, заполняемая при входе в функцию значениями и очищаемая после выхода из ф-ции. Она при входе в ф-цию заполнилась value-типами и ссылками на reference-типы (в том числе и ссылкой на массив - переменная arrInt является ссылкой на массив, члены которого хранятся в куче). При выходе из ф-ции она очистилась - value-типы и ссылки на reference-типы уничтожились (в том числе, ячейка, хранящая адрес массива и называющаяся переменной arrInt). Сами reference-типы еще остались в куче, до сборки мусора (все ячейки, содержащие реальные значения элементов массива arrInt).
конечно они не в стеке. Они в куче, а вот указатель на них (область памяти, выделенную для хранения их всех) - он как раз в стеке
Я предлагаю вообще никому про боксинг не упоминать. Это только путает. Боксинг для того, чтобы число передать в виде объекта кому-нибудь. И все. Допустим число создано внутри метода. Оно хранится в стеке. Вызываем метод MyFunc(object o) или Console.Write(object o). Мы можем передать наше число, которое счас в стеке. Но компилятор упакует его в object - т.е. создаст в куче объект (с возможностями типа object), инициализирует его числом и передаст в метод. В стеке наше число останется. В куче новый объект появится. То же самое будет в случае, когда приводим число к объекту явно... Закончили работу - стек с числом очистился, оникому уже не нужный объект в куче остался. Лучше про боксинг пока не упоминать... Это НЕ ОТНОСИТСЯ к методам работы стека и кучи. Это работа компилятора для согласования типов данных. Код пришли и мне, плиз. ivashkanet дай плиз ссылку на место, где упоминается про "небольшиуе массивы хранятся в стеке " просто я слышал, что создавать стековые массивы нужно специально. (тоже в той книжке. что упоминал, там, где указатели описываются) Может в 3.0 появилось? -------------------- На хорошей работе и сны хорошие снятся. |
||||||
|
|||||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Нет, про массивы я все же не видел. Только про List<T>. Но он же сделан на основе масссива... Добавлено через 6 минут и 5 секунд А я о таком даже не слышал. Можно мне ссылку |
|||
|
||||
| mr.DUDA |
|
||||||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Ага, наконец-то я услышал что хотел: элементы массива хранятся в куче! Вот это и сбивает с толку. Как это value-type может в куче быть. Наверно, надо Рихтера всё-таки почитать З.Ы. Пример с пулом структур: Предположим, есть у нас некая структура данных с размером этак 100..200 байт. Таких классов или структур (назовём её Particle, хотя название и назначение не суть важно), может понадобиться создавать много. Ну к примеру, иметь 10000 экземпляров одновременно. Варианты как делать это: 1. Объявить классом и создавать с пом. new по необходимости; хранить где угодно - в List<> например. Неэффективно ввиду GC, особенно если объекты хранятся долго и попадают в 1-е а то и 2-е поколение сборки мусора 2. Объявить структурой и также создавать с пом. new, хранить в массиве или List<> или др. типизированной коллекции. Этот вариант лучше чем №1 ввиду того что юзаем непрерывные массивы, состоящие из структур (List<> тоже массив юзает), никакого боксинга и никаких затрат на GC. Поясняю: массив структур во время сборки мусора рассматривается как 1 объект. Недостатки всё же есть: - если юзать массив, теряем возможность добавления/удаления элементов - если юзать List или другую коллекцию, получаем затраты на удаление элемента - в List.RemoveAt весь хвост сдвигается вверх с пом. Array.Copy() - в случае доступа по индексу List возвращает копию а не экземпляр структуры, о чём говорил ivashkanet; это лишние затраты которых желательно избегать в случае "толстых" структур (более 4 байт) 3. Наконец, вариант с пулом структур. Остановлюсь подробнее на этом. Под простейшим пулом структур в моём понятии подразумевается коллекция, аналогичная List<>, позволяющая добавлять, удалять элементы и проходить по ним в цикле. Внутри себя это обычный массив структур, обёрнутый парой методов - Alloc, Remove(i) и выставляющий тот самый массив как public-поле. Вот примеры кода:
З.Ы.Ы. за нарушение принципов ООП не ругать! Я о них знаю Добавлено через 41 секунду ivashkanet,
См. оператор stackalloc, но он возвращает указатель а не массив, и требует unsafe. -------------------- ![]() |
||||||
|
|||||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
может и офф-топик. но все же...
А что тогда вообще в куче может быть, по-твоему? Класс, у которого два поля и оба int. Он в куче. А его два поля где? тоже в куче. В куче выделено два блока памяти для хранения двух int Так же и массив. int[10] - в куче выделен блок памяти для хранения десяти int Спасибо за код. Я посмотрю, но комментировать не буду. Просто интересный вариант, со своим правом на существование ... ivashkanet, ссылка - "С# 2005 для профессионалов", -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| Azzdorf |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 190 Регистрация: 29.3.2007 Репутация: нет Всего: нет |
ок простой вопрос
когда мы жмем три чудесные кнопочки и запускаем в Винде (да будет проклят Билл) в диспечере задач --> закладку Процессы там есть колонки: Память и Вирувальная память Вопрсы: Какая-то из них показывает размер Кучи или Стека или это что-то не то?????? И ефективно ли запускать GC после нагруженых методов и функций??? --------------------
Иногда шаг вперед - это результат хорошего пинка под зад. |
|||
|
||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 63 Всего: 170 |
Данные для 32-битной Windows
размер стека: по умолчанию под стек каждого потока выделяется 1МБайт памяти. (это для "юзания" программой, не учитывает объемы системмных областей) размер кучи: по умолчанию для каждого процесса выделяется 4Гбайт виртуальной памяти. Профайлерами, если не ошибаюсь. То, что ты видишь в диспечере задач - это используемый сейчас объем памяти Да, эффективно. Именно поэтому в public интерфейс и выведены члены класса GC, чтобы с ними работать -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| Azzdorf |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 190 Регистрация: 29.3.2007 Репутация: нет Всего: нет |
физической или оперативной??? Добавлено через 2 минуты если оперативной то тогда почему моя маленькая простая прога ест 48метров, когда тотже запищеный файл ворда - 10метров??? --------------------
Иногда шаг вперед - это результат хорошего пинка под зад. |
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |