Re[8]: Нетривиальные проблемы с GC
От: Cyberax Марс  
Дата: 11.09.07 16:52
Оценка:
Здравствуйте, WolfHound, Вы писали:

C>>Между процессами или отображаемыми в память файлами.

WH>Детали.
Ну ты базу данных используешь? Так ведь она (О ужас!) тоже распределяется между процессами.

C>>Одно слово: кэши.

WH>Какие и сколько данных в кеше?
32 мегабайта Это встроеное устройство.

C>>Я с его помощью сделал почти прозрачное транзакционное disk-backed кэширование (операционная система еще и предоставляет кэширование в памяти).

WH>Транзакционное? Что-то както сомневаюсь.
WH>В самом Boost.Interprocess нет упоминаний о транзакциях.
Там есть упоминания о мьютексах.

WH>А самому их делать

Совсем несложно — я и в обычном стиле почти так же пишу.

C>>По скорости ничего даже близко не приближается.

WH>Тоже не факт.
Пробовал SQLite, MySQL и db4o. У меня быстрее всего работает, что совсем неудивительно.
Sapienti sat!
Re[8]: Нетривиальные проблемы с GC
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.09.07 16:59
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


E>>Я считал, что проблема фрагментации памяти для new/delete (malloc/free) заключается в другом. В том, что адресное пространство процесса постоянно растет. Что приводит к частым попаданиям мимо кэша или слишком частым вытеснениям занятых процессом страниц памяти в своп.

GZ>Та программа была под Dos и выполнялась на 286/386 машинах. Так что не было ни кэша, ни свопа.

Да уж, представляю себе САПР под Dos-ом на 286 на менеджед языке со сборкой мусора

С тех пор не только железо лучше стало, но и алгоритмы malloc-а (dlmalloc, к примеру).

E>>Что особо чувствительно для 24x7 процессов, которые месяцами не выгружаются и не останавливаются.

GZ>Когда работал на С++, для серверов изначально не использовал STL по данной причине. Сейчас уже не знаю, по дурости или без. Поэтому сказать ничего не могу.

Я использую, но вот с фрагментацией не сталкивался.

E>>А то, о чем ты написал -- это просто неподходящий алгоритм выделения памяти для конкретной задачи. Непосредственно к проблеме явного управления памяти он, имхо, не имеет отношения.

GZ>Отчего же. GC — позволяет дефрагментировать память, и обходиться без прохода по спискам выделенных/пустых областей. То — что не умеет malloc. Так что замечание было в тему.

Линейный список блоков в аллокаторе -- это уже история. Я надеюсь


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: Нетривиальные проблемы с GC
От: WolfHound  
Дата: 11.09.07 17:26
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Ну ты базу данных используешь? Так ведь она (О ужас!) тоже распределяется между процессами.

Это ты вобще к чему?

C>32 мегабайта Это встроеное устройство.

Лично я кеши десятками гигабайт меряю...

Кстати, а зачем на встроеном устройстве кешь. Да еще и расшаренный между процессами.

C>Там есть упоминания о мьютексах.

И? С каких это пор мьютексы обеспечивают транзакции?

C>Совсем несложно — я и в обычном стиле почти так же пишу.

Я какбы писал код гарантирующий ACID.

C>Пробовал SQLite, MySQL и db4o. У меня быстрее всего работает, что совсем неудивительно.

Правильно. Там есть транзакции, а у тебя их нет.
По крайней мере ты так и не сказал откуда они взялись.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Нетривиальные проблемы с GC
От: Cyberax Марс  
Дата: 11.09.07 17:35
Оценка:
Здравствуйте, WolfHound, Вы писали:

C>>Ну ты базу данных используешь? Так ведь она (О ужас!) тоже распределяется между процессами.

WH>Это ты вобще к чему?
Это про shared-данные.

C>>32 мегабайта Это встроеное устройство.

WH>Лично я кеши десятками гигабайт меряю...
Это неинтересно. Туда можно и RAID-массив воткнуть и пару гигабайт памяти.

WH>Кстати, а зачем на встроеном устройстве кешь. Да еще и расшаренный между процессами.

Там есть несколько процессов, собирающих данные с разных устройств, процесс-обработчик и закачивальщик результата на центральный сервер.

И это все асинхронно работает.

C>>Там есть упоминания о мьютексах.

WH>И? С каких это пор мьютексы обеспечивают транзакции?
Это у меня основной инструмент для их обеспечения.

C>>Совсем несложно — я и в обычном стиле почти так же пишу.

WH>Я какбы писал код гарантирующий ACID.
А я писал ACID? У меня, на самом деле, ACI (без D — его дейстивительно сложно делать).

C>>Пробовал SQLite, MySQL и db4o. У меня быстрее всего работает, что совсем неудивительно.

WH>Правильно. Там есть транзакции, а у тебя их нет.
Есть, с оптимистическим версированием. При коммите блокирую нужные объекты (мьютексами), проверяю версии и заливаю обновления.
Sapienti sat!
Re[11]: Нетривиальные проблемы с GC
От: WolfHound  
Дата: 11.09.07 19:27
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Это неинтересно. Туда можно и RAID-массив воткнуть и пару гигабайт памяти.

Восемь.

C>Там есть несколько процессов, собирающих данные с разных устройств, процесс-обработчик и закачивальщик результата на центральный сервер.

C>И это все асинхронно работает.
По описанию идеально ложится на объмен сообщениями вобще и ОСь типа сингулярити в частности.

C>Это у меня основной инструмент для их обеспечения.

Ну то что без блокировок транзакции не сделать это и так ясно.

C>Есть, с оптимистическим версированием. При коммите блокирую нужные объекты (мьютексами), проверяю версии и заливаю обновления.

Те что-то типа STM?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Нетривиальные проблемы с GC
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.07 21:24
Оценка: 14 (3)
Здравствуйте, GlebZ, Вы писали:

E>>А то, о чем ты написал -- это просто неподходящий алгоритм выделения памяти для конкретной задачи. Непосредственно к проблеме явного управления памяти он, имхо, не имеет отношения.

GZ>Отчего же. GC — позволяет дефрагментировать память, и обходиться без прохода по спискам выделенных/пустых областей. То — что не умеет malloc. Так что замечание было в тему. ;)

Нет, не в тему. Алгоритмы распределения памяти с линейными списками благополучно начали дохнуть ещё в конце 80-х и окончательно сдохли к середине 90-х по причине того, что проход по спискам безнадёжно замусоривал кэши процессоров. Все новые алгоритмы в этот период писались уже с построением деревьев занятости и структурами для оптимизации поиска по желаемому размеру, а для мелких объектов — пулов фиксированного размера с внешними таблицами занятости (как правило, битовыми массивами). Сейчас же имеем ещё дополнительно 15 лет вылизывания этих алгоритмов.

Так что говорить, что malloc "не умеет" "обходиться без прохода по спискам выделенных/пустых областей" означает безнадёжно отставать от современного опыта, пользуясь данными не просто прошлого тысячелетия, а как минимум раннего допотопья.:) Признайтесь — Вы небось ни одну современную реализацию malloc не смотрели, а про списки областей вычитали где-нибудь в книгах написанных в лучшем случае в начале 80-х, а задуманных в конце 70-х? У Вирта? ;)))

E>>Что особо чувствительно для 24x7 процессов, которые месяцами не выгружаются и не останавливаются.

GZ>Когда работал на С++, для серверов изначально не использовал STL по данной причине. Сейчас уже не знаю, по дурости или без. :-\ Поэтому сказать ничего не могу.

Видимо, таки по ней, родимой:) — иначе сложно назвать ориентирование на данные двадцатилетней давности.
The God is real, unless declared integer.
Re[7]: Нетривиальные проблемы с GC
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.07 22:31
Оценка: 2 (1) +2
Здравствуйте, eao197, Вы писали:

E>Я считал, что проблема фрагментации памяти для new/delete (malloc/free) заключается в другом. В том, что адресное пространство процесса постоянно растет. Что приводит к частым попаданиям мимо кэша или слишком частым вытеснениям занятых процессом страниц памяти в своп. Что особо чувствительно для 24x7 процессов, которые месяцами не выгружаются и не останавливаются.


Что-то не замечал подобного эффекта и плохо себе представляю, как его можно получить. Даже если реализация способна только забирать память у системы и не возвращать, а нагрузка постоянна (или колеблется с периодом значительно меньше набранного времени жизни процесса), то потребление памяти должно стабилизироваться на уровне немного большем, чем необходимо для держания всех данных. "Немного" зависит от разнообразия размера объектов и может быть хоть 1.5, но оно постоянно для шаблона потребления. Если же объём памяти постоянно растёт — это скорее признак какой-то утечки, нежели метода работы с памятью. Наблюдение за долгоживущими нагруженными серверами (из моих подопечных это innd, squid, ircd, netmond, sendmail, exim и так далее) подтверждает эту теорию.

О фрагментации имеет смысл говорить, если был пик нагрузки значительно выше обычного уровня (при котором действительно были проблемы кэша и свопа) и затем она упала до обычного уровня. В этом случае вполне вероятно иметь множество слабозаполненных страниц, в тяжёлом случае по 1-2 живых объекта на страницу. Но в любом случае такое растёт из прошлого всплеска.

Ряд программ реализует защиту от подобного использованием своего менеджера памяти, но не ради оптимизации по размеру или чему-то подобному, а ради возможности потом одной порцией устранить пул памяти, использованный, например, под обработку одного запроса:) Такие реализации лишены большей части проблем с недоиспользованием. Оборотная сторона — необходимость полностью контролировать выделение памяти в коде с использованием нужного менеджера — приводит к почти полной потере возможности использовать стандартные библиотеки. Шаблонные классы C++ с заданием аллокатора порождены именно подобной спецификой.

E>А то, о чем ты написал -- это просто неподходящий алгоритм выделения памяти для конкретной задачи. Непосредственно к проблеме явного управления памяти он, имхо, не имеет отношения.


Угу.
The God is real, unless declared integer.
Re[2]: Нетривиальные проблемы с GC
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 12.09.07 02:37
Оценка:
Здравствуйте, eao197, Вы писали:

E>Справедливости ради нужно сказать, что в C++, к счастью, есть возможность создавать объекты на стеке и передавать их по значению. Что часто очень серьезно снижает количество операций new/delete.

В Java SE 6 реализован т.н. Escape-анализ: вумный JIT может принять решение о выделении памяти под объекты на стеке, нежели массиве — так что стек (неявно, конечно) доступен и в GC-средах.
Re[8]: Нетривиальные проблемы с GC
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.09.07 04:01
Оценка:
Здравствуйте, netch80, Вы писали:

E>>Я считал, что проблема фрагментации памяти для new/delete (malloc/free) заключается в другом. В том, что адресное пространство процесса постоянно растет. Что приводит к частым попаданиям мимо кэша или слишком частым вытеснениям занятых процессом страниц памяти в своп. Что особо чувствительно для 24x7 процессов, которые месяцами не выгружаются и не останавливаются.


N>Что-то не замечал подобного эффекта и плохо себе представляю, как его можно получить. Даже если реализация способна только забирать память у системы и не возвращать, а нагрузка постоянна (или колеблется с периодом значительно меньше набранного времени жизни процесса), то потребление памяти должно стабилизироваться на уровне немного большем, чем необходимо для держания всех данных. "Немного" зависит от разнообразия размера объектов и может быть хоть 1.5, но оно постоянно для шаблона потребления. Если же объём памяти постоянно растёт — это скорее признак какой-то утечки, нежели метода работы с памятью. Наблюдение за долгоживущими нагруженными серверами (из моих подопечных это innd, squid, ircd, netmond, sendmail, exim и так далее) подтверждает эту теорию.


N>О фрагментации имеет смысл говорить, если был пик нагрузки значительно выше обычного уровня (при котором действительно были проблемы кэша и свопа) и затем она упала до обычного уровня. В этом случае вполне вероятно иметь множество слабозаполненных страниц, в тяжёлом случае по 1-2 живых объекта на страницу. Но в любом случае такое растёт из прошлого всплеска.


Об этом я и говорил. Наверноее выразился неудачно.

Тем более, что на практике с фрагментацией памяти я пока не встречался.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Нетривиальные проблемы с GC
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.09.07 04:06
Оценка: -1
Здравствуйте, rsn81, Вы писали:

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


E>>Справедливости ради нужно сказать, что в C++, к счастью, есть возможность создавать объекты на стеке и передавать их по значению. Что часто очень серьезно снижает количество операций new/delete.

R>В Java SE 6 реализован т.н. Escape-анализ: вумный JIT может принять решение о выделении памяти под объекты на стеке, нежели массиве — так что стек (неявно, конечно) доступен и в GC-средах.

Речь шла не о том, что в управляемых средах нет стека, а о том, что в C++ стековые объекты и объекты по значению значительно уменьшают использование new/delete, что приводит к уменьшению проблем с явным управлением памятью.

А в Java, что есть стек, что его нет, как создавались все объекты через new, так и создаются.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Нетривиальные проблемы с GC
От: Пётр Седов Россия  
Дата: 12.09.07 04:37
Оценка: 63 (4) +2
Здравствуйте, eao197, Вы писали:

E>при использовании GC выделение памяти обходится (по слухам) дешевле C-шных malloc-ов, а освобождается затем всем скопом,

В C++ тоже можно создать много структур, а потом освободить их всех одним махом. При этом вполне можно обойтись без хитрых алгоритмов сборки мусора. Правда есть одна тонкость: каждая структура должна иметь тривиальный деструктор, чтобы его можно было не вызывать.
Вот несколько примеров.

1. Страуструп в книге «Дизайн и эволюция языка C++»
Автор(ы): Бьерн Страуструп

В книге, написанной создателем языка C++ Бьерном Страуструпом, представлено описание
процесса проектирования и разработки языка программирования C++. Здесь изложены цели,
принципы и практические ограничения, наложившие отпечаток на структуру и облик C++,
обсужден дизайн недавно добавленных в язык средств: шаблонов, исключений, идентификации
типа во время исполнения и пространств имен. Автор анализирует решения, принятые в ходе
работы над языком, и демонстрирует, как правильно применять реальный
объектно-ориентированный язык программирования.
пишет:

Глава 10. Управление памятью

10.4. Размещение объекта в памяти

Для конкретной арены operator new() можно определить так:

void* operator new(size_t s, fast_arena& a)
{
  return a.alloc(s);
}

а использовать следующим образом:
void f(fast_arena& arena)
{
  X* p = new(arena) X; // распределить X на арене
  // ...
}

Здесь предполагается, что fast_arena — это класс, который имеет функцию-член alloc(), применяющуюся для выделения памяти. Например:
class fast_arena {
  // ...
  char* maxp;
  char* freep;
  char* expand(size_t s); // получить дополнительную память от
                          // распределителя общего назначения
public:
  void* alloc(size_t s) {
    char* p = freep;
    return ((freep += s) < maxp) ? p : expand(s);
  }
  void free(void*) { } // ничего не делает
  clear();             // освободить всю выделенную память
};

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

10.5. Проблемы освобождения памяти

Идеальный вариант — тот, при котором пользователю вообще не нужно освобождать память, занятую объектом. Для этого, в частности, применяются специальные арены. Арену можно определить так, что в некоторой известной точке программы будет освобождаться вся память, занятая этой программой. Можно также написать для неё сборщик мусора. Первый подход очень распространён, второй — нет. Специальный сборщик мусора должен быть написан удачно, иначе проще встроить в программу стандартный [Boehm, 1993].


2. JPEG lib, файл jpeg-6b\structure.doc:

*** Memory manager services ***

In all cases, allocated objects are tied to a particular compression or decompression master record, and they will be released when that master record is destroyed.

The memory manager does not provide explicit deallocation of objects. Instead, objects are created in "pools" of free storage, and a whole pool can be freed at once. This approach helps prevent storage-leak bugs, and it speeds up operations whenever malloc/free are slow (as they often are). The pools can be regarded as lifetime identifiers for objects. Two pools/lifetimes are defined:
* JPOOL_PERMANENT lasts until master record is destroyed
* JPOOL_IMAGE lasts until done with image (JPEG datastream)

Кстати, замечание про медленные malloc/free — это преданье старины глубокой. Joseph Newcomer в статье «Оптимизация &mdash; ваш злейший враг»
Автор(ы): Dr. Joseph M. Newcomer
Дата: 25.06.2005
В этом эссе доктор Ньюкамер делится своим опытом и соображениями по поводу преждевременной, несвоевременной или неактуальной оптимизации, призывая программистов избежать подобных ошибок.
пишет:

Когда-то, во времена зарождения языка C, его распределитель памяти был самым слабым из существующих. Это был алгоритм «первый попавшийся», то есть он работал следующим образом: распределитель просматривал все узлы в списке блоков памяти, и первый же попавшийся свободный блок, который был не меньше нужного размера, разбивался на две части — одна возвращалась по запросу, вторая (общий размер блока минус запрошенный размер) возвращалась в список свободных узлов. «Преимущества» этого очевидны — очень низкая скорость работы и дикая фрагментация памяти. В действительности это хуже, чем вы можете себе представить. При выделении памяти приходилось пробегать весь список блоков, игнорируя уже выделенные. Поэтому при увеличении числа блоков производительность падала, а блоки становились всё меньше и были непригодны к использованию. Они отнимали время без всякой реальной пользы.

Я сходил в свой кабинет, где лежала копия книги IDL, принёс её с собой назад, и открыл главу «Распределение памяти».

«Я написал эту главу, в которой рассказывается о разработке высокопроизводительного, минимально фрагментирующего распределителя памяти.»

Распределитель памяти в NT работает весьма схожим образом с тем, что я описал в книге IDL, и основан на алгоритме «быстрого совпадения», разработанном Чаком Вейнстоком для его докторской в CMU около 1974 года.


3. Распределитель памяти в Quake 2. Файл quake2-3.21\qcommon\common.c:

#define Z_MAGIC 0x1d1d


typedef struct zhead_s
{
  struct zhead_s *prev, *next;
  short magic;
  short tag; // for group free
  int size;
} zhead_t;

zhead_t z_chain;
int z_count, z_bytes;
...
void Z_Free (void *ptr)
{
  zhead_t *z;

  z = ((zhead_t *)ptr) - 1;

  if (z->magic != Z_MAGIC)
    Com_Error (ERR_FATAL, "Z_Free: bad magic");

  z->prev->next = z->next;
  z->next->prev = z->prev;

  z_count--;
  z_bytes -= z->size;
  free (z);
}
...
void Z_FreeTags (int tag)
{
  zhead_t *z, *next;

  for (z=z_chain.next ; z != &z_chain ; z=next)
  {
    next = z->next;
    if (z->tag == tag)
      Z_Free ((void *)(z+1));
  }
}
...
void *Z_TagMalloc (int size, int tag)
{
  zhead_t *z;

  size = size + sizeof(zhead_t);
  z = malloc(size);
  if (!z)
    Com_Error (ERR_FATAL, "Z_Malloc: failed on allocation of %i bytes",size);
  memset (z, 0, size);
  z_count++;
  z_bytes += size;
  z->magic = Z_MAGIC;
  z->tag = tag;
  z->size = size;

  z->next = z_chain.next;
  z->prev = &z_chain;
  z_chain.next->prev = z;
  z_chain.next = z;

  return (void *)(z+1);
}
...
void *Z_Malloc (int size)
{
  return Z_TagMalloc (size, 0);
}
...
void Qcommon_Init (int argc, char **argv)
{
  ...
  z_chain.next = z_chain.prev = &z_chain;
  ...
}

Файл quake2-3.21\game\g_local.h:

// memory tags to allow dynamic memory to be cleaned up
#define TAG_GAME 765 // clear when unloading the dll
#define TAG_LEVEL 766 // clear when loading a new level


4. Пример
Автор: Пётр Седов
Дата: 20.06.07
простой арены, без виртуальной памяти.
Пётр Седов (ушёл с RSDN)
Re[3]: Нетривиальные проблемы с GC
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.09.07 04:43
Оценка: +1
Здравствуйте, Пётр Седов, Вы писали:

ПС>Здравствуйте, eao197, Вы писали:


E>>при использовании GC выделение памяти обходится (по слухам) дешевле C-шных malloc-ов, а освобождается затем всем скопом,

ПС>В C++ тоже можно создать много структур, а потом освободить их всех одним махом. При этом вполне можно обойтись без хитрых алгоритмов сборки мусора. Правда есть одна тонкость: каждая структура должна иметь тривиальный деструктор, чтобы его можно было не вызывать.
ПС>Вот несколько примеров.

<...примеры поскипаны...>

Все это так, но это все меняет код программы или требует каких-то специальных условий. В то время как GC оставляет текст программы в первоначальном виде (как были new, так и остались, вне зависимости от расположения объектов в хипе или на стеке).


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Нетривиальные проблемы с GC
От: Пётр Седов Россия  
Дата: 12.09.07 04:53
Оценка:
Здравствуйте, eao197, Вы писали:
GZ>>Дефрагментация.
E>Если чесно, то никогда с этой проблемой на практике не сталкивался.
Например, Erop сталкивался
Автор: Erop
Дата: 26.02.07
.
Пётр Седов (ушёл с RSDN)
Re: Нетривиальные проблемы с GC
От: Pavel Dvorkin Россия  
Дата: 12.09.07 06:21
Оценка:
Здравствуйте, remark, Вы писали:

<все skipped после чтения данного сообщения и ответов>

У меня на все это одна мысль возникла. А почему бы авторам некоей системы программирования не совместить GC и не-GC в одной коробке ? То есть ввести в систему GC и его управление памятью, но в то же оставить и возможность выделять/освобождать память вручную. 2 кучи — одна управляемая a la C#-Java, вторая — неуправляемая a la C++. И были бы и волки сыты и овцы целы. Выбирай, что тебе больше нравится и что больше соотвествует твоей задаче. А может быть, даже и в рамках одной задачи выбирать и то и другое для разных объектов.

Кстати, то же относится к деструктированию объектов. Почему бы не сделать так, чтобы программист мог либо поручить это GC, либо сказать — делай детерминированно сейчас ?

Никаких принципиальных причин, почему это невозможно, я не вижу (если кто видит — скажите). Конечно, в нынешние языки и системы это не лезет. Может, пора новый язык/систему создать с такими возможностями.
With best regards
Pavel Dvorkin
Re[6]: Нетривиальные проблемы с GC
От: Пётр Седов Россия  
Дата: 12.09.07 06:22
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Было много мелких объектов, алгоритм должен был быть очень быстрым. При выделении памяти — стандартный malloc проходил по всей цепочке пытаясь найти место, в результате проседала производительность. Пришлось переопределять new, и делать свой менеджер памяти.

Если алгоритм создаёт много мелких структур и по окончании алгоритма эти структуры становятся не нужны, то лучше использовать не heap (malloc/free или глобальные new/delete), а арену — это такой распределитель памяти вроде stack-а. Вообще, мимолётные временные структуры лучше размещать в арене. Тогда и фрагментация heap-а меньше будет.

GZ>Примерно такая-же ситуация была с VirtualAlloc(работает по тому же принципу).

Переопределить VirtualAlloc не получится .
Пётр Седов (ушёл с RSDN)
Re[2]: Нетривиальные проблемы с GC
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.07 06:29
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD><все skipped после чтения данного сообщения и ответов>


PD>У меня на все это одна мысль возникла. А почему бы авторам некоей системы программирования не совместить GC и не-GC в одной коробке ? То есть ввести в систему GC и его управление памятью, но в то же оставить и возможность выделять/освобождать память вручную. 2 кучи — одна управляемая a la C#-Java, вторая — неуправляемая a la C++. И были бы и волки сыты и овцы целы. Выбирай, что тебе больше нравится и что больше соотвествует твоей задаче. А может быть, даже и в рамках одной задачи выбирать и то и другое для разных объектов.


Ну вот вопрос с ходу. Как отслеживать ссылки из не-GC пула в GC пул?

PD>Кстати, то же относится к деструктированию объектов. Почему бы не сделать так, чтобы программист мог либо поручить это GC, либо сказать — делай детерминированно сейчас ?


А смысл? Проще ввести счётчик ссылок и удалять объект сразу как только у него счётчик упадёт до нуля. GC после этого остаётся только для случаев циклической зависимости, и то — программист может помочь этому разорвав циклы в нужных местах.
Так работает, кстати, python — на долю GC остаются только сложные циклические конструкции.

PD>Никаких принципиальных причин, почему это невозможно, я не вижу (если кто видит — скажите). Конечно, в нынешние языки и системы это не лезет. Может, пора новый язык/систему создать с такими возможностями. :-)
The God is real, unless declared integer.
Re[2]: Нетривиальные проблемы с GC
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.09.07 06:31
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>У меня на все это одна мысль возникла. А почему бы авторам некоей системы программирования не совместить GC и не-GC в одной коробке ? То есть ввести в систему GC и его управление памятью, но в то же оставить и возможность выделять/освобождать память вручную. 2 кучи — одна управляемая a la C#-Java, вторая — неуправляемая a la C++. И были бы и волки сыты и овцы целы. Выбирай, что тебе больше нравится и что больше соотвествует твоей задаче. А может быть, даже и в рамках одной задачи выбирать и то и другое для разных объектов.
Совершенно непонятно, как должна себя вести такая комбинация. Что делать GC, если на управляемый им объект есть ссылки из неуправляемой им кучи? Как ему вообще понять, есть ли эти ссылки?

PD>Кстати, то же относится к деструктированию объектов. Почему бы не сделать так, чтобы программист мог либо поручить это GC, либо сказать — делай детерминированно сейчас ?

И какую семантику это будет иметь? Ну то есть вот допустим есть объект в управляемой куче, и мы говорим "умри!". Использовать место, ранее занимаемое этим объектом, до компактификации кучи всё равно нельзя. Точнее, неоправданно дорого. Делать упаковку сразу — еще дороже. Чем это поможет GC? Если речь не об освобождении памяти (которое GC и так неплохо проводит), то разрушение сводится к вызову определенного метода, после которого объект считается мертвым. В нынешних языках и системах такой метод называется Dispose() и для удобства объявлен в интерфейсе IDisposable.

PD>Никаких принципиальных причин, почему это невозможно, я не вижу (если кто видит — скажите).

Как только ты придумаешь ответы на эти принципиальные вопросы, отличающиеся от того, что есть сейчас, можно приниматься создавать новый язык.
PD>Конечно, в нынешние языки и системы это не лезет. Может, пора новый язык/систему создать с такими возможностями.
В одной коробке совместить коня и трепетную лань не получается. Получается развести их по разным коробкам, что можно наблюдать невооруженным взглядом в нынешних языках и системах в полный рост.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Нетривиальные проблемы с GC
От: Pavel Dvorkin Россия  
Дата: 12.09.07 07:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Совершенно непонятно, как должна себя вести такая комбинация. Что делать GC, если на управляемый им объект есть ссылки из неуправляемой им кучи? Как ему вообще понять, есть ли эти ссылки?


Из неуправляемой кучи ссылок на управляемые объекты и обратно быть не должно. Не держишь же ты в С++ куче ссылки на автоматические объекты в стеке
Я просто предлагаю разделить эти два множества без пересечения. Если же оно все же потребуется, то идти по пути, аналогичному boxing-unboxing.

PD>>Кстати, то же относится к деструктированию объектов. Почему бы не сделать так, чтобы программист мог либо поручить это GC, либо сказать — делай детерминированно сейчас ?

S>И какую семантику это будет иметь? Ну то есть вот допустим есть объект в управляемой куче, и мы говорим "умри!". Использовать место, ранее занимаемое этим объектом, до компактификации кучи всё равно нельзя. Точнее, неоправданно дорого. Делать упаковку сразу — еще дороже. Чем это поможет GC? Если речь не об освобождении памяти (которое GC и так неплохо проводит), то разрушение сводится к вызову определенного метода, после которого объект считается мертвым. В нынешних языках и системах такой метод называется Dispose() и для удобства объявлен в интерфейсе IDisposable.

С этим соглашусь.

S>В одной коробке совместить коня и трепетную лань не получается.


Почему ? Совместили же в C# кучу и стек. Я не вижу, почему стек с GC может в одной коробке уживаться, а неуправляемая куча нет. В конце концов стек от неуправляемой кучи отличается только механизмом выделения/освобожденяи памяти, если уж на то пошло
With best regards
Pavel Dvorkin
Re[2]: Нетривиальные проблемы с GC
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 12.09.07 07:39
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>У меня на все это одна мысль возникла. А почему бы авторам некоей системы программирования не совместить GC и не-GC в одной коробке ? То есть ввести в систему GC и его управление памятью, но в то же оставить и возможность выделять/освобождать память вручную.


C++/CLI ?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Re[4]: Нетривиальные проблемы с GC
От: Pavel Dvorkin Россия  
Дата: 12.09.07 07:51
Оценка:
PD>Почему ? Совместили же в C# кучу и стек. Я не вижу, почему стек с GC может в одной коробке уживаться, а неуправляемая куча нет. В конце концов стек от неуправляемой кучи отличается только механизмом выделения/освобожденяи памяти, если уж на то пошло

Вдогонку. А кстати, почему в C# жестко привязали тип объектов (object или value) к способу размещения (куча или стек). Почему нельзя value разместить в куче или object в стеке ? Это принципиально или просто особенность реализации ?
With best regards
Pavel Dvorkin
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.