Re[4]: Пара примеров
От: johny5 Новая Зеландия
Дата: 09.01.15 14:16
Оценка:
Здравствуйте, andyag, Вы писали:

J>>В С++ эта модульность — спасительный круг в мире висящих указателей, определённый функционал просто не будет запущен если какое то условие на более высоком уровне не было выдержано. В данном случае какой то блок внутри Модуля 1 будет просто отключен и что какие ссылки и структуры он содержит и куда оно всё ссылается оно всё становится неважно. По сути это приводит к повышению требования к качеству ООП в С++.


A>Не очень понятно. Обычно отключение куска кода — это в простейшем случае if вокруг какого-то флажка. Этим флажком кто-то должен управлять. В вашей иллюстрации, скорее всего, тот самый компонент, который "кто-то, кто явно убивает модуль 2". Убийство объекта это не delete, и не вызов сборщика мусора. Это в первую очередь заявление "этот объект теперь неактуален".


Да, так и есть, только этим флажком необязательно управлять извне. Модуль 1 может сам позаботиться о получении этого флажка. Да через тот же синглетон. Впрочем важно ли как этот флажок получен? Тут ведь главное что если флажок сброшен то какой то кусок модуля 1, который держит связь со 2м, не будет запущен.

Расширим тот же пример с кнопкой и звуковым менеджером. Пусть кнопка является частью музыкального проигрывателя.
Проигрыватель, для эффективности, может содержать прямые ссылки на звуки из менеджера (закешированные) и дёргать их по мере надобности. Но в момент когда ты нажимаешь кнопку "Play", проигрыватель сначала проверит всё ли окей с менеджером звуков, и если нет, выдаст сообщение об ошибке и прервёт проигрывание.

Тут, главное, что ты не задумываешься о том что звук твой может тянуть за собой весь драйвер, тебе вообще без разницы как эти звуки там реализованы, оптимизации идут отдельным сапом и они не влияют на высокоуровневые построения логики никак. Ты знаешь контракт что пока менеджер звуков жив — на нём можно играть звуки. Это ты и проверяешь.

Код не приведу, видно что пример притянут за уши. Организм требует сна, ничего более реалистичного в голову не приходит, впрочем я уверен вполне что реальных примеров уйма. Я очень надеюсь что объяснил ясно.
Re[4]: Просто сначала надо читать, а потом писать...
От: johny5 Новая Зеландия
Дата: 09.01.15 14:19
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Здравствуйте, johny5, Вы писали:


J>>Здравствуйте, 11molniev, Вы писали:


J>>Кстате напомнило, в С++ когда ты объекту явно говоришь "умри", он сам мог отписаться автоматом от всего на что его подписали, используя boost::signals::trackable. Одна строка и досвиданья.


J>https://www.google.ru/search?ie=UTF-8&hl=ru&q=c%23%20weak%20events&gws_rd=ssl

J>Это?

Было дело, искал.

Нашлось куча хаков и это, которое AFAIK не поддерживает WPF.

Похоже weak подписки пока не тренд в C#.
Re[3]: Просто сначала надо читать, а потом писать...
От: 11molniev  
Дата: 09.01.15 14:30
Оценка:
Здравствуйте, johny5, Вы писали:

1>> Ссылки надо подчистить не на форму, а на модель (в С++ вы удаляете объект на который у вас ещё есть ссылки?). Срабатывает в ста случаях корректного использования (десятки лет эксплуатации .Net/Java подтверждают это).


J>Кстате напомнило, в С++ когда ты объекту явно говоришь "умри", он сам мог отписаться автоматом от всего на что его подписали, используя boost::signals::trackable. Одна строка и досвиданья.


J>Не нашёл подобного механизма в C#, кроме того я вабще не понял как можно там отписываться. Ввод прокси объекта и занулять там указатель, это единственный вариант сделать подобное в C#?


Классические события C# предполагают, что время жизни объекта источника событий меньше времени жизни получателя, т.е. отписываться надо руками (желающие могут делать это из деструктора). Поскольку эти события были заложены в первую очередь для GUI, где время жизни объектов UI априори меньше времени жизни объектов реализующих логику приложения (по крайне мере, если код не лапша) то такой подход вполне логичен.

Но если на секундочку вспомнить, что boost таки библиотека, можно за пару минут найти прямой аналог boost:signal для C#: RX. Ну или при небольшом желании написать свой диспетчер событий, даже офигенно затюненгованная под многопоточность и конкретные паттерны потока событий такая штука вроде не очень сложна...
Re[5]: Просто сначала надо читать, а потом писать...
От: 11molniev  
Дата: 09.01.15 14:36
Оценка:
Здравствуйте, johny5, Вы писали:

J>>>Кстате напомнило, в С++ когда ты объекту явно говоришь "умри", он сам мог отписаться автоматом от всего на что его подписали, используя boost::signals::trackable. Одна строка и досвиданья.

J>>https://www.google.ru/search?ie=UTF-8&hl=ru&q=c%23%20weak%20events&gws_rd=ssl
J>>Это?
J>Было дело, искал.
J>Нашлось куча хаков и это, которое AFAIK не поддерживает WPF.
J>Похоже weak подписки пока не тренд в C#.
Извиняюсь, что вмешиваюсь, но если вам нужны подобные штуки для отработки событий между WPF и логикой программы — значит вы все же делаете что то ну совсем не то...
Re[3]: Garbage collection vs manual memory management
От: VladD2 Российская Империя www.nemerle.org
Дата: 09.01.15 14:46
Оценка: +1 :)
Здравствуйте, 0BD11A0D, Вы писали:

BDA>Забавляет, потому, что многие забывают, что «профессионал» производное от «профессия» (и пишется с одной «ф»). Распространять ужостики про другие языки — характерная часть этой профессии, потому, что язык очень часто используется неоправдано, и если этого не делать — их поувольняют и заменят более дешевыми.


Согласен со всем кроме более дешевых. Хороший специалист дешево не стоит. Я замечал за сиплюсплюсниками эдакое завышенное самомнение, что мол на других языках пишут те кто с плюсами не справляется. Это не более чем раздутое ЧСВ.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Garbage collection vs manual memory management
От: Sinix  
Дата: 09.01.15 16:11
Оценка:
Здравствуйте, johny5, Вы писали:


J>А тогда как вы иначе делаете Load данных с диска, убиваете и пересоздаёте форму целиком?

Как правило, достаточно кода вида
class AppState
{
  public Document CurrentState;
  public event EventHandler CurrentStateChanged:

  public void Load(...) { ... }
}


UI просто обрабатывает события/изменение свойств. AppState не убивается и живёт, пока живо приложение (или форма, тут как удобнее).

J>Прокси — понятно.

Тут нет прокси Прокси — эт класс с тем же api, который перенаправляет вызовы обёрнутому объекту. Тут просто свойство.

S>>Вообще-то в wpf нет кэша. И как раз в wpf эта проблема решается элементарно — биндингом

J>Да нет, он там есть
Автор: johny5
Дата: 31.01.14
.

А это не кэш, это утечка памяти в wpf. Если не забуду, завтра поищу пример. Там скорее всего двойной баг: элементы списка не реализуют INotifyPropertyChanged + утечка из-за AutomationPeer.

В .net 4.6 обещали поправить.
Ссылки:
http://ayende.com/blog/4296/reproducing-a-wpf-memory-leak
https://social.msdn.microsoft.com/Forums/vstudio/en-US/1525407e-194b-440e-b316-93f8ff076abc/wpf-4-touch-automationpeer-windows-7-tablet-input-services-memory-leak?forum=wpf

и крышесносящий саппорт вот в этой ветке:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/33828e1b-224a-4b73-86b5-9af949f07508/installing-net-452-breaks-microsofts-recommended-disablewpftabletsupport-method-for-disabling?forum=wpf

J>Биндинг помоему тоже создаёт жёсткую ссылку, но тут неуверен. Как чистить ссылки биндинга — ума не приложу.

Не, там нет жёсткой ссылки. Зато есть баг, который приводит к утечке, если прибинденные к гриду записи не реализуют INotifyPropertyChanged.
Re: Garbage collection vs manual memory management
От: Кодт Россия  
Дата: 09.01.15 16:26
Оценка: +2
Здравствуйте, johny5, Вы писали:

J>Общались с Джавистом пересевшим на С++. Мол висящие указатели, явная чистка памяти, и т.д. Всё это плохо и известно. Он предлагает универсальное решение — shared_ptr на всё. Я задал контрольный вопрос: есть кнопка, к ней привязан звук из менеджера звуков. Мы решили перегрузить менеджер звуков. Нам для этого старый нужно удалить а в новом все звуки загрузить заново. И что я слышу от него, оказывается это нормально в данном случае что кнопка на UI не даст старому звуковому менеджеру умереть!! А если там нужно драйвер переиниализировать, старый обязательно должен выгрузить своё.


J>Я до сих пор в шоке. Это ужос для С++ профессионала, вдруг оказаться в языке где ты не можешь контролировать жизнь объектов вокруг тебя.


Ужос состоит в том, что и плюсовики, и менеджедчики в равной степени обольщаются и переупрощают видение ситуации.
Надо взять перфоратор, алмазное долото и бетонный блок. И выдолбить большими буквами:
НЕ СВАЛИВАЙТЕ В ОДНУ КУЧУ УПРАВЛЕНИЕ ПАМЯТЬЮ И ДРУГИЕ ВОПРОСЫ ВЛАДЕНИЯ.

В плюсах, например, типичнейшая грабля — это управление жизнью взаимозависимых синглетонов.
Можно изобретать всякие хитроумные политики, как это ещё Александреску показал в 2004 году, но, в конце концов, это сведётся не более чем к автоматизации и уменьшению синтаксического шума вокруг продуманной, проговоренной и написанной на бумажке стратегии: как чего поднимать и как чего убивать.

Если у программы есть такой юз-кейс "перезагрузить менеджер звуков", то пусть лучше это будет явная функция с явным вызовом всех соответствующих недр. А не "let them crash".
Безотносительно того, на shared_ptr всё это добро сделано или на delete.
Пусть у менеджера будет метод "самозачиститься", который выполняет то же, что и деструктор, но без окончательного самоубийства.
И пусть пользователи менеджера могут убедиться, что он полудохлый, и не упасть при этом, а переключиться на актуальный экземпляр менеджера.

Уж на то пошло, это делается на двойной косвенности.
class SoundManager // всё, что вы хотели иметь от этого менеджера
{
public:
  SoundManager(.....); // код загрузки здесь
  ~SoundManager(); // код выгрузки здесь (в т.ч. через деструкторы членов-данных и баз)
  .....
};

class SoundManagerHolder
{
  unique_ptr<SoundManager> man_;
  void load()     { man_ = make_unique<SoundManager>(.....); }
  void lazyload() { if(!man_) load(); }
  void unload()   { man_.reset(); }
public:
  explicit SoundManagerHolder(bool start) { if(start) load(); }
  SoundManager& get() const
  {
    lazyload();
    return *man_;
  }
  void reset(bool restart)
  {
    unload();
    if(restart) load();
  }
};
typedef shared_ptr<SoundManagerHolder> SoundManagerPointer; // распоряжайтесь.
Перекуём баги на фичи!
Re[4]: Garbage collection vs manual memory management
От: 0BD11A0D  
Дата: 09.01.15 18:50
Оценка: :)
Здравствуйте, VladD2, Вы писали:

BDA>>Забавляет, потому, что многие забывают, что «профессионал» производное от «профессия» (и пишется с одной «ф»). Распространять ужостики про другие языки — характерная часть этой профессии, потому, что язык очень часто используется неоправдано, и если этого не делать — их поувольняют и заменят более дешевыми.


VD>Согласен со всем кроме более дешевых. Хороший специалист дешево не стоит.


Во-первых, хороший специалист для кого? Для себя он хорош, или для работодателя? У них разные интересы (иногда диаметрально). По моим субъективным ощущениям, примерно в 75% случаев хороший программист, независимо от языка, должен сказать: «Тут программист не нужен» и уйти в закат. Без денег. Показывала тут знакомая проект, над которым работает — веб-аппы для маркетологов. У маркетологов у всех есть законный Excel. Вместо того, чтобы сделать за полчаса выгрузку в XML, пилят «онлайн-аналитику». Я говорю, зачем этим мудакам онлайн? Они в метро на смартфоне работают? На айпадике? Или в офисе на стуле за компьютером с Excel'ем? То, что вы тут собрали, это же корявее всякого допотопного офиса-шмофиса. Как только что-нибудь изменится, опять вас звать. Она говорит, наверное, пользоваться не умеют, да и что за печаль? Главное, платят. Это еще вам случай, когда работодатель действовал заодно с хорошим специалистом, напарив заказчика. Потом специалист начинает напаривать самого работодателя, типа, тут не обойтись без того, сего и этого. Ох, щас прочитают профессионалы этот мой анонимный донос, и дадут просраться! Стоит ли удовольствие от беседы последующего потока гавна — сам не знаю. Нет, наверное, просто не фейсбучиться же для расслабона.

Ладно, едем дальше. Во-вторых, даже если они будут получать одинаковую зарплату, человек, неоправданно протащивший плюсы, обойдется среднестатистически дороже. У него больше возможностей запутать код (а раз он протащил ненужный язык, можно ли надеяться, что он не протащит и ненужный код?). Он тупо дольше будет управлять памятью и отлаживаться. Больше ошибок будет в релизе и бороться с ними сложнее. Заменить такого труднее. Все это деньги.

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

В-четвертых, я не говорил, что кто-то дешевый, а кто-то дорогой. Я сказал — ДЕШЕВЛЕ. Посмотрите объявления — до 110 шарп, до 120 плюсы. До 60 P (пэ), до 90 плюсы. Если бы плюсовикам нечего было защищать, они бы так себя не вели.

В-пятых, как ни крути, управлять памятью требует больших знаний, а плюсы сложнее. И бывает, что без них не обойтись. Я всего лишь говорил о том, что суют их куда ни попадя. С подачи паразита в собственном теле — ИТ-директора какого-нибудь. Который хочет больше бюджетов, а не меньше, представьте себе.

Извините, тут про программирование, да про философию, а я все про жизнь. Впредь все обязуюсь и больше не.
Re[6]: Garbage collection vs manual memory management
От: johny5 Новая Зеландия
Дата: 10.01.15 02:11
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, johny5, Вы писали:



J>>А тогда как вы иначе делаете Load данных с диска, убиваете и пересоздаёте форму целиком?

S>Как правило, достаточно кода вида
S>
S>class AppState
S>{
S>  public Document CurrentState;
S>  public event EventHandler CurrentStateChanged:

S>  public void Load(...) { ... }
S>}
S>


S>UI просто обрабатывает события/изменение свойств. AppState не убивается и живёт, пока живо приложение (или форма, тут как удобнее).


J>>Прокси — понятно.

S>Тут нет прокси Прокси — эт класс с тем же api, который перенаправляет вызовы обёрнутому объекту. Тут просто свойство.

Проперти в общем не защитит от проблемы, мы получим незащищённый указатель на модель в сыром виде. Модель окажется напрямую связанной со всеми UI контролами и выгрузить её не получится.
Re[5]: Пара примеров
От: andyag  
Дата: 10.01.15 07:26
Оценка: 8 (1)
Здравствуйте, johny5, Вы писали:

J>Здравствуйте, andyag, Вы писали:


J>>>В С++ эта модульность — спасительный круг в мире висящих указателей, определённый функционал просто не будет запущен если какое то условие на более высоком уровне не было выдержано. В данном случае какой то блок внутри Модуля 1 будет просто отключен и что какие ссылки и структуры он содержит и куда оно всё ссылается оно всё становится неважно. По сути это приводит к повышению требования к качеству ООП в С++.


A>>Не очень понятно. Обычно отключение куска кода — это в простейшем случае if вокруг какого-то флажка. Этим флажком кто-то должен управлять. В вашей иллюстрации, скорее всего, тот самый компонент, который "кто-то, кто явно убивает модуль 2". Убийство объекта это не delete, и не вызов сборщика мусора. Это в первую очередь заявление "этот объект теперь неактуален".


J>Тут, главное, что ты не задумываешься о том что звук твой может тянуть за собой весь драйвер, тебе вообще без разницы как эти звуки там реализованы, оптимизации идут отдельным сапом и они не влияют на высокоуровневые построения логики никак. Ты знаешь контракт что пока менеджер звуков жив — на нём можно играть звуки. Это ты и проверяешь.


Вы как-то очень размыто используете термин "жив". В простейшем случае будет как-то вот так:
class SoundManager {
  void playSound() {...}
}

class SoundPlayer {
  SoundManager soundManager = null;

  public void playSound() {
    if(soundManager == null) { // тот самый if с флажком
      throw new RuntimeException("There's no sound manager");
    }

    soundManager.playSound();
  }

  public void setSoundManager(SoundManager soundManager) {
    this.soundManager = soundManager;
  }
}

...

SoundPlayer player = new SoundPlayer();

player.playSound(); // throws

player.setSoundManager(new SoundManager("sound manager one"));
player.playSound(); // works

player.setSoundManager(null);
player.playSound(); // throws

Если вы имеете в виду ситуацию, когда существующий SoundManager по какой-то причине становится невалидным, это уже не настолько тривиальный кейз. Можно сделать например вот так:
interface IDisconnectable {
  void setOnDisconnectedListener(OnDisconnectedListener listener);
}

class SoundManager implements IDisconnectable {
  ...
}

class SoundPlayer implements OnDisconnectedListener {
  void setSoundManager(SoundManager soundManager) {
    if(this.soundManager != null) {
      this.soundManager.setOnDisconnectedListener(null);
    }

    this.soundManager = soundManager;
    soundManager.setOnDisconnectedListener(this);
  }

  void onDisconnected(SoundManager sender) {
    sender.setOnDisconnectedListener(null);
    this.soundManager = null;
  }

  public void playSound() {
    if(soundManager == null) { // и снова - тот самый if с флажком
      throw new RuntimeException("There's no sound manager");
    }

    soundManager.playSound();
  }
}

Если не хочется так накручивать SoundPlayer, можно сделать SoundManagerHolder extends SoundManager, который будет хранить ссылку на настоящий SoundManager до тех пор, пока тот SoundManager не скажет, что он поломался. Пока не поломался — все вызовы будет делегировать настоящему объекту (если есть) или кидать исключения (если нет).
Re[7]: Garbage collection vs manual memory management
От: Sinix  
Дата: 10.01.15 09:07
Оценка:
Здравствуйте, johny5, Вы писали:

J>Проперти в общем не защитит от проблемы, мы получим незащищённый указатель на модель в сыром виде. Модель окажется напрямую связанной со всеми UI контролами и выгрузить её не получится.

Почему? AppState задаётся как DataContext окна, меняем модель — биндинг сам подхватит изменения.
Re[8]: Garbage collection vs manual memory management
От: johny5 Новая Зеландия
Дата: 10.01.15 09:12
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, johny5, Вы писали:


J>>Проперти в общем не защитит от проблемы, мы получим незащищённый указатель на модель в сыром виде. Модель окажется напрямую связанной со всеми UI контролами и выгрузить её не получится.

S>Почему? AppState задаётся как DataContext окна, меняем модель — биндинг сам подхватит изменения.

Хм.. а как это в XAML могло бы выглядеть?
Re[5]: Garbage collection vs manual memory management
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.01.15 12:42
Оценка:
Здравствуйте, 0BD11A0D, Вы писали:

BDA>Во-первых, хороший специалист для кого? Для себя он хорош, или для работодателя? У них разные интересы (иногда диаметрально). ...


Хороший специалист — это человек умеющие реализовывать нужную функциональность, решать возникающие на этот пути проблемы. Короче, тот кто может делать дело в разумные сроки.

BDA>Ладно, едем дальше. Во-вторых, даже если они будут получать одинаковую зарплату, человек, неоправданно протащивший плюсы, обойдется среднестатистически дороже. У него больше возможностей запутать код (а раз он протащил ненужный язык, можно ли надеяться, что он не протащит и ненужный код?). Он тупо дольше будет управлять памятью и отлаживаться. Больше ошибок будет в релизе и бороться с ними сложнее. Заменить такого труднее. Все это деньги.


Когда говорят о стоимости специалиста, то ведут речь о зарплате.

С тем, что производительность труда сиплюсплюсника (скорее всего) будет существенно ниже нежели производительность столь же профессионального программиста на безопасном языке с GC никто не спорит. Точнее спорят как раз такие "сиплюсплюс-специалисты" с раздутым ЧСВ.

Но плюсы могут оказаться и оптимальным решением. Например, в вычислительно сложных задачах они могут дать несколько процентов производительности, что может оказаться остаточным конкурентным преимуществом.

BDA>В-третьих, не будут они получать одинаковую зарплату. Разнорабочий плюсовик получает больше разнорабочего шарпея. Достаточно посмотреть объявления от одного и того же нанимателя.


Я не знаю кто такие разнорабочие. У меня достаточно примеров когда те кто пишет на шарпе получают больше своих коллег пишущих на плюсах. Зарплата скорее зависит от уровня знаний, страны, города, компании, нежели от языка на котором пишет человек.

Ну, а у зарплата губов меня мало интересует. Тут все очевидно порог вхождения в шарпа существенно ниже нежели в плюсы.

BDA>В-четвертых, я не говорил, что кто-то дешевый, а кто-то дорогой. Я сказал — ДЕШЕВЛЕ. Посмотрите объявления — до 110 шарп, до 120 плюсы. До 60 P (пэ), до 90 плюсы. Если бы плюсовикам нечего было защищать, они бы так себя не вели.


Мы вроде говорили о профессионалах/специалистах. За 60 тры, да и за 90 тыр найти спепциалиста не реально. По крайней мере в Москве или Питере. С поправкой на местность, валюту и базовую ставку это справедливо для любого места на земле.

BDA>В-пятых, как ни крути, управлять памятью требует больших знаний, а плюсы сложнее.


Это откровенная глупость. Управление памятью в ручную не требует больше знаний, так же как не требует больших знание поддержание в рабочем состоянии советских Волг. Просто это неприятная ручная работа. Да, тут нужен опыт. Да ошибиться легко, а значит нужны усидчивость, аккуратность и т.п. Но это не знания.

Человеку работающему над каким-нибудь искусственным интеллектом знания нужны куда больше. И найти специалиста способно решать такие задачи в стол раз сложнее нежели найти специалиста умеющего управлять памятью вручную.

Лично я долгое время писал на С и С++. Мог бы заниматься этим а дальше, но мне просто жалко тратить свое время на совершенно бессмысленную тупую работу вроде управление памятью и обход прочих граблей.

BDA>Извините, тут про программирование, да про философию, а я все про жизнь. Впредь все обязуюсь и больше не.


Дык, здесь "Философия программирования", а не о жизни.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Garbage collection vs manual memory management
От: _NN_ www.nemerleweb.com
Дата: 11.01.15 09:22
Оценка:
Здравствуйте, Кодт, Вы писали:

К>НЕ СВАЛИВАЙТЕ В ОДНУ КУЧУ УПРАВЛЕНИЕ ПАМЯТЬЮ И ДРУГИЕ ВОПРОСЫ ВЛАДЕНИЯ.


С этим абсолютно согласен.
Сборщик мусора решает проблему утечки памяти но никак не проблему утечек ресурсов.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Garbage collection vs manual memory management
От: Nuseraro Россия  
Дата: 11.01.15 20:50
Оценка: +1 :)
А сама компиляция в машинные коды? Вы видели, что получается? Это вообще какой-то мракобесный оверхед!

Невозможность контролировать результирующий машинный код — неприемлемо для меня, поэтому пишу только на кошерном асме.
Homo Guglens
Re: Garbage collection vs manual memory management
От: chaotic-good  
Дата: 13.01.15 13:09
Оценка:
J>Я до сих пор в шоке. Это ужос для С++ профессионала, вдруг оказаться в языке где ты не можешь контролировать жизнь объектов вокруг тебя.

Не все объекты требуют контролировать свое время жизни. Скажем объект "соединение с БД" имеет время жизни, оно начинается после того, как ты коннектишься к БД и заканчивается после того, как ты сделаешь close. Это время жизни управляется явным образом что в С++, что в C# и Java. Просто методы разные, в С++ с этим получше, так как есть семантика значений и RAII. Есть еще время жизни объекта как куска памяти в куче, оно начинается когда ты делаешь new и заканчивается после delete. Это как раз то, за что отвечает GC. В твоем примере идет речь о первом времени жизни:

J>Я задал контрольный вопрос: есть кнопка, к ней привязан звук из менеджера звуков. Мы решили перегрузить менеджер звуков. Нам для этого старый нужно удалить а в новом все звуки загрузить заново. И что я слышу от него, оказывается это нормально в данном случае что кнопка на UI не даст старому звуковому менеджеру умереть!! А если там нужно драйвер переиниализировать, старый обязательно должен выгрузить своё.


оставить его на откуп GC будет ошибкой в Java/C#. Большинство объектов в программе, это обекты, которые могут легко управляться сборщиком мусора, это делает программирование проще не потому что не нужно удалять объекты вручную, а потому, что делает невозможным появление мертвых ссылок/указателей. Тоесть, даже если ты забыл поменять ссылку на звук в кнопке, а звуковой менеджер создал новый а старый выкинул, ссылка внутри кнопки продолжит указывать на старый менеджер.

J>Вопрос к вам ко всем, каков стиль программирования должен быть чтобы можно было бы писать на GC языках. Как добиваться модульности, ООП, когда не всё тянет всё, а модуль сам за себя и свои части отвечает. И, в частности, как вы делаете загрузку выгрузку данных модели, ведь от старых данных так просто не избавишься даже если ты скажешь Clear() всем контейнерам.


Несколько простых правил для перемещающих сборщиков мусора:
1) new/delete и подсчет ссылок в С++ больше подходят для долгоживущих объектов, которые создаются надолго, GC больше подходит для короткоживущих объектов, если загружаешь модель — делай это в одном месте и сразу выбрасывай ссылку на объект модели, чтобы он не попал в следующее поколение. В этом случае, сборка будет быстрой.
2) если объект долгоживущий, желательно чтобы он был неизменяемым, если ты создал крупный граф объектов, который пережил множество сборок мусора и попал в самое долгоживущее поколение, изменение объектов в нем будет приводить к полной пересборке мусора. Это противоположенно тому, что обычно делают в плюсах/Си — там лучше создавать удалять объекты пореже, чтобы не тратить время в аллокаторе. Вот например пулл объектов в GC языке будет плохо работать, обекты в пулле живут долго но инициализируются периодически заново нагружая GC, в GC языке лучше не использовать пуллы объектов а просто создавать объекты когда нужно в куче и не заморачиваться, это банально быстрее.
3) почитать статьи про IDisposable в С# (и его аналог в Java) и научиться его использовать
Re[2]: Garbage collection vs manual memory management
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.01.15 15:45
Оценка: +1
Здравствуйте, chaotic-good, Вы писали:

CG>2) если объект долгоживущий, желательно чтобы он был неизменяемым, если ты создал крупный граф объектов, который пережил множество сборок мусора и попал в самое долгоживущее поколение, изменение объектов в нем будет приводить к полной пересборке мусора. Это противоположенно тому, что обычно делают в плюсах/Си — там лучше создавать удалять объекты пореже, чтобы не тратить время в аллокаторе. Вот например пулл объектов в GC языке будет плохо работать, обекты в пулле живут долго но инициализируются периодически заново нагружая GC, в GC языке лучше не использовать пуллы объектов а просто создавать объекты когда нужно в куче и не заморачиваться, это банально быстрее.


На практике это не так.
Основные тормоза создаются при генерации мусора. Меньше мусора == реже сборки == выше производительность даже при более дорогих сборках мусора.
Пулы объектов в языках с GC работают прекрасно.
Re[3]: Garbage collection vs manual memory management
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.01.15 15:53
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, Кодт, Вы писали:


К>>НЕ СВАЛИВАЙТЕ В ОДНУ КУЧУ УПРАВЛЕНИЕ ПАМЯТЬЮ И ДРУГИЕ ВОПРОСЫ ВЛАДЕНИЯ.


_NN>С этим абсолютно согласен.

_NN>Сборщик мусора решает проблему утечки памяти но никак не проблему утечек ресурсов.

Речь вообще не об утечках, а о том, что ручное управление памятью создает целый класс ошибок из-за невалидных указателей.
Чтобы избежать таких ошибок надо четко следовать стратегии управления владением объектов.

GC исправляет этот класс ошибок, но может привести к "утечкам" из-за хранения ссылок на объекты, которые уже не используются.
И снова нужно следовать стратегии управления владением, чтобы таких ошибок избежать.

Исходный вопрос касался как раз владения и имеет отдаленное отношение к управлению памятью.
Re[2]: Garbage collection vs manual memory management
От: GarryIV  
Дата: 13.01.15 15:53
Оценка:
Здравствуйте, chaotic-good, Вы писали:

CG>Не все объекты требуют контролировать свое время жизни. Скажем объект "соединение с БД" имеет время жизни, оно начинается после того, как ты коннектишься к БД и заканчивается после того, как ты сделаешь close. Это время жизни управляется явным образом что в С++, что в C# и Java. Просто методы разные, в С++ с этим получше, так как есть семантика значений и RAII.


А в Java есть АОП. Для управления транзакциями и конекшенами это намного интереснее RAII.
WBR, Igor Evgrafov
Re[3]: Garbage collection vs manual memory management
От: chaotic-good  
Дата: 13.01.15 20:10
Оценка:
G>На практике это не так.
G>Основные тормоза создаются при генерации мусора. Меньше мусора == реже сборки == выше производительность даже при более дорогих сборках мусора.

И при этом лучше, когда мусор короткоживущий. Ну и не только мусор, нужно в целом о структурах данных думать с позиции GC (в том числе), стараться делать из более gc-friendly, чтобы создавать меньше работы для сборщика мусора, pointer chasing в стиле С/С++ тут до добра не доведет.

G>Пулы объектов в языках с GC работают прекрасно.


У меня был случай, когда я на практике наблюдал обратное — после выпиливания пулла и замены его на обычный new, все стало работать быстрее и приложение стало проводить меньше времени за сборкой мусора. В принципе, это становится очевидно и если просто почитать про устройство gc в .net, в msdn есть очень хорошая статья на эту тему, ты должно быть ее читал. Пулл объектов может работать хорошо, если ссылки внутри этих объектов не меняются, только данные, соответственно не дергается сборка в gen 2, но в общем случае, пуллы рекомендовать нельзя, особенно для короткоживущих объектов.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.