Для работы проектов iXBT.com нужны файлы cookie и сервисы аналитики.
Продолжая посещать сайты проектов вы соглашаетесь с нашей
Политикой в отношении файлов cookie
101175546080106411874@google
Комментатор
Arioch The
Рейтинг
+5.00
Автор не входит в состав редакции iXBT.com (подробнее »)
Но вот саму перезагрузку можно, конечно, и побыстрее бы делать.
Только для этого придется под обновления 25-35% диска отдать, а это ж жаба задушит :-)
.
не хватало мне еще, потеряв телефон или словив на него вирус, лишиться всех денег.
.
телефон — это развлекалка, для серьезных дел нужно отдельное что-то.
.
> чтобы сообщить GC, что объект по выходе из блока больше не нужен
.
Ну сообщили, и что? захочет GC — его освободит сразу, а захочет — послезавтра. Это ЕГО решение, а не вашей программы.
.
Детерминированно — в момент выхода из Using-блока — вызывается тоьлко обычный метод .Dispose(). Который по сути ничем не отличается от других сеттеров состояния, типа SetColorRed() или SetFontItalic(). В частности я очень сомневаюсь, что компилятор проверяет, что в этом методе мы 1) освобождаем ВСЕ ресурсы, 2) ТОЛЬКО освобождаем ресурсы, 3) освобождаем ВСЕ ОСТАЛЬНЫЕ ресурсы даже при любых возникающих в процессе освобождения любого из ресурсов ошибках.
.
Я, кстати, беру свои слова про элегантность обратно. Идея-то хорошая, но реализация...
https://habr.com/ru/post/89720/
https://docs.microsoft.com/ru-ru/dotnet/standard/garbage-collection/implementing-dispose
https://metanit.com/sharp/tutorial/8.2.php
.
class MyDiposableClass {
......
private bool disposed = false;
// реализация интерфейса IDisposable.
public void Dispose()
{
Dispose(true);
// подавляем финализацию
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Освобождаем управляемые ресурсы
// наконец-то делаем что-то полезное
}
// освобождаем неуправляемые объекты
// и тут тоже наконец делаем что-то полезное
disposed = true;
}
}
.
Ехала трамвае голая старушка....
.
Delphi:
destructor Destroy; override; { virtual methods overriding should be explicitly marked }
begin
FreeMem (MyPtr1);
FreeMem (MyPtr2);
MyArray := nil;
MyARCObject := nil;
end;
.
или C++
.
~ClassTypeName()
{
free(MyPtr1);
free(myPtr2);
delete [] MyArray;
delete MyObj;
}
.
В «тупых примитивных» языка код освобождения ресурсов занимает меньше, чем в C# элегантные тонны бойлерплейта, которые даже ещё и не начали ничего освобождать вообще.
.
И если среди этого бойлерплейта ты забудешь освободить ресурс — то будет такая же ошибка, как в «тупом традиционном» языке — вот только хрен ты её так просто среди этого всего словесного (verbose) мусора разглядишь.
.
> И да, мы *сообщаем* GC, что объект можно собрать.
.
Нет!
.
static obj = MyDisposableObject();
static ctr = SomeObjectsContainer();
obj.Dispose();
ctr.Add(obj);
.
Это что, в самом деле GC теперь может удалить объект, при живой на него ссылке из контейнера? Серьезно???
Ничего подобного мы GC не сообщили.
.
Мы просто вызвали — в действительно элегантной сахарной обёртке — метод установки состояния объекта Dispose(); Внутри которого те ещё тараканы бегают, оказывается.
.
> С этой точки зрения нам монопенисуально — почистили память в момент, когда мы этого захотели, или только когда она реально потребовалась.
.
Точно. Мы НЕ УПРАВЛЯЕМ временем жизни объектов. Мы принципиально от этого отказалась и наняли уборщицу, как в гостиницах. Пусть она сама приходит, когда посчитает нужным, роется по нашим шкафам и сумкам, и выкидывает, что посчитает лишним. Хорошая, дорогая уборщица сделает это почти незаметно. Мы принципиально не можем сами выбросить мусор, вообще. Мы можем только попытаться нанять уборщицу еще лучше и дороже, и НАДЕЯТЬСЯ, что она будет убирать тот мусор и когда, когда нам нужно. Ну или мы написали Блокнот и нам просто не важно много там мусора или мало накопилось.
.
Но что прискорбно, при всем этом горничная занимается уборкой ТОЛЬКО памяти. Остальные ресурсы — окна, файлы, сетевые соединения, звуковые и прочее — она убирать не умеет. И их нам приходится убирать в том же самом ручном режиме, как и 20 лет назад в «тупом примитивном» C++. Только бойлерплейта стало больше, и увы у новичков путаницы. Они ведь реально не закрывают файл, потому что «функция кончилась — объект умер и файл сам освободился — у нас есть GC».
.
А кроме того, 100% оптимизированная программа не чистит память никогда. Это всегда потеря производительности. Лучше, чтобы без нее.
А на 99% оптимизированная программа чистит свою память (освобождает и отдает системе) ооочень редко, например раз в час.
Потому что ЕЙ это не надо, это другим программам надо, но какого чёрта ей снижать СВОЮ производительность заботами о других.
И вот когда в системе запускается полсотни GC-positive процессов, вдруг оказывается, что 2 ГБ — 2 миллиарда байтов — этого мало, чтобы просто открыть сотню анекдотов в интернете.
> чтобы сообщить GC, что объект по выходе из блока больше не нужен
Ну сообщили, и что? захочет GC — его освободит сразу, а захочет — послезавтра. Это ЕГО решение, а не вашей программы.
Детерминированно — в момент выхода из Using-блока — вызывается тоьлко обычный метод .Dispose(). Который по сути ничем не отличается от других сеттеров состояния, типа SetColorRed() или SetFontItalic(). В частности я очень сомневаюсь, что компилятор проверяет, что в этом методе мы 1) освобождаем ВСЕ ресурсы, 2) ТОЛЬКО освобождаем ресурсы, 3) освобождаем ВСЕ ОСТАЛЬНЫЕ ресурсы даже при любых возникающих в процессе освобождения любого из ресурсов ошибках.
Я, кстати, беру свои слова про элегантность обратно. Идея-то хорошая, но реализация...
https://habr.com/ru/post/89720/
https://docs.microsoft.com/ru-ru/dotnet/standard/garbage-collection/implementing-dispose
https://metanit.com/sharp/tutorial/8.2.php
private bool disposed = false;
// реализация интерфейса IDisposable.
public void Dispose()
{
Dispose(true);
// подавляем финализацию
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Освобождаем управляемые ресурсы
}
// освобождаем неуправляемые объекты
disposed = true;
}
}
Ехала трамвае голая старушка....
Delphi:
destructor Destroy; override; { virtual methods overriding should be explicitly marked }
begin
FreeMem (MyPtr1);
FreeMem (MyPtr2);
MyArray := nil;
MyARCObject := nil;
end;
или C++
~ClassTypeName()
{
free(MyPtr1);
free(myPtr2);
delete [] MyArray;
delete MyObj;
}
В «тупых примитивных» языка код освобождения ресурсов занимает меньше чем в C# элегантные тонны бойлерплейта, которые даже ещё и не начали ничего освобождать.
И если среди этого бойлерплейта ты забудешь освободить ресурс — то будет такая же ошибка, как в «тупом традиционном» языке — вот только хрен ты ее так просто среди этого всего мусора разглядишь.
> И да, мы *сообщаем* GC, что объект можно собрать.
Нет!
static obj = MyDisposableObject();
static ctr = SomeObjectsContainer();
obj.Dispose();
ctr.Add(obj);
Это что, в самом деле GC теперь может удалить объект, при живой на него ссылке из контейнера? Серьезно???
Ничего подобного мы GC не сообщили.
Мы просто вызвали — в красивой сахарной обёртке — метод установки состояния объекта Dispose(); Внутри которого те еще тараканы бегают, оказывается.
> С этой точки зрения нам монопенисуально — почистили память в момент, когда мы этого захотели, или только когда она реально потребовалась.
Точно. То есть 100% оптимизированная программа не чистит память никогда. Это всегда потеря производительности. Лучше, чтобы без нее.
А на 99% оптимизированная программа чистит свою память (освобождает и отдает системе) ооочень редко, например раз в час.
Потому что ЕЙ это не надо, это другим программам надо, но какого чёрта ей снижать СВОЮ производительность заботами о других.
И вот когда в системе запускается полсотни GC-positive процессов, вдруг оказывается, что 2 ГБ — 2 миллиарда байтов — этого мало, чтобы просто открыть сотню анекдотов в интернете.
.
А умный аллокатор — это совершенно не GC-специфичная вещь. В «тупых традиционных» языках они десятилетиями были.
.
Да и в принципе один из основных посыл Го был «назад к истокам». Слишком далеко в лес забрели, надо возвращаться к практичным решениям.
.
Кроме почти традиционного подхода к управлению кучей, из Го насколько знаю выкинули исключения, которые принято считать обязательной частью любого современного императивного языка.
.
И у Раста такая же стартовая идея, хотя он категорически не согласен с Го что именно выкидывать.
.
А до них обоих был D, у которого и сегодня есть преданные поклонники. Но он, наверное, был слишком рано.
.
Вообще, это симптоматично, что два самых обсуждаемых и быстрорастущих языка основаны на идее «надо идти назад»
.
Это не управление жизнью. Это просто меняет состояние объекта.
.
obj.SetColor(Red);
obj.Dispose();
obj.SetActive(False);
.
Это все просто сеттеры состояний.
При этом я согласен, что iDisposable + using — весьма элегантный костыль для невозможности удалить объект. Ничего лучше не придумали. Syntactic sugar, конечно. Но такой, что жабисты справедливо обзавидовались, и бросились где возможно передирать :)
.
Но это не деструктор и не удаление объекта.
Удаление было и остается случайным процессом вне контроля программы. Это фундамент самой концепции мусорщиков.
.
При этом внутри Dispose у нас внезапно что? Ручное освобождение ресурсов. Типа закрыть файл, закрыть сетевой сокет, закрыть окно и т.д.
.
Вроде бы мы завели мусорщика, чтобы он освобождал ресурсы, но тут же вводим новый метод специально, чтобы заниматься освобождением ресурсов вместо мусорщика. Это забавно.
.
> Через какое-то время непрерывной работы ЛЮБОЙ программы в такой среде выделенная память превращается в решето
.
Гипотетически, если выделять память на авось, в расчете что «придет мусорщик и дефрагментирует».
Но ведь это не обязательно так.
В любой программе образуются корневые, долгоживущие объекты. Объекты живущие поменьше, совсем короткоживущие. И если память первых действительно становится «лежачим камнем», то остальные постепенно освободятся. И если не пихать между ними явно неподжодящие по размеру куски — то снова сольется в олин большой свободный кусок.
.
> Положили туда 300кб — осталась дырка в 200
.
А стоит ли ее оставлять? Может быть лучше ее ТОЖЕ выделить? В качестве slack space, буфера для роста, для realloc ?
.
Это если вообще втискивать туда эту память. Ведь аллокатор тоже может заняться разные зоны разбивать на блоки разного размера например.
.
При этом разным классам можно выделять память в разных кучах с разными менеджерами. Безусловно, в программе типа Блокнот никто не будет с этим заморачиваться, но в такой программе и stop world GC ничем не мешает.
.
А если программа на C# долдна выбирать из как минимум двух GC, предсказывая свои потребности в памяти и скорости, то почему программа на C++ не может точно также выбирать из нескольких heap managers под свои нужды?
.
Если конкретно Microsoft C++ поставляется безальтернативно с менеджером, который не умеет склеивать освобожденные блоки, и который нельзя заменить — это проблема не нативных языков вообще, а конкретно Microsoft C++.
.
Опять же, а много ли в самом деле программ, которые должны работать месяцами, и у которых при этом непредсказуемое выделение памяти? Взять какой-нибудь торрент клиент, например. Каждый торрент разбивается на куски одинакового, фиксированного размера.
.
… и кстати, сравнение uTorrent и Azureus прекрасно показывает как хорошо GC экономит память :)
Ведь именно это утверждалось в первом комментарии, что программы на GC языках используют меньше памяти, чем традиционные.
.
> мелкие дырки в котором особо ничем не заполняются,
.
Я уже выше писал, что память разделяется на зоны, для блоков разных размеров.
.
Среди мелочи не образуется решета, потому что все размеры округляются вверх до местной нормы. А крупные объекты выделяются в другом месте.
.
Безусловно, это не панацея, и не так и трудно написать Win32 программу, которая будет выделять память гигабайтами, и там нарваться на фрагментацию в самом деле очень легко. Но это именно потому, что мы требуем непрерывный кусок, сравнимый с адресным пространство в целом. Потому что это либо очень ленивый подход к написанию очень специальной программы с требованиями на грани технически возможного. А при таком подходе ты с любой технологией нарвешься на ее слабые места. Либо это чисто синтетический пример, когда программа намеренно выводится на запредельные режимы, чтобы было что в документацию вставить.
Вы влезли в чужой разговор, чтобы с баааальшим апломбом сказать, что вы ничего не поняли.
Хотя обычно неспособностью понять не гордятся, а стесняются ее.
Почему то древний ЖЖ догадывается разбить текст на абзацы без этого геморроя. Про кучу форумов с Markdown не говорю.
Но на крутом, «вылизанном до блеска» и «научившемуся новому» iXBT 2020 — надо левой рукой правое ухо чесать. Независимо от того, надо или не надо.
Кстати, на Discus подобный глюк строго привязан к UNIX(в т.ч. Android) браузерам. У Windows другой маркер конца строк и он распознаётся.
.
Другой GC воткнуть — да. Но даже поменять GC на ARC — как?
Вы предполагаете, что программа не должна управлять временем жизни объектов. Что любая выделенная память остается выделенной пока кому-то извне программы не захочется ее освободить, попутно уничтожая наконец объекты.
В таком определении эффективности конечно ничего кроме GC быть не может.
Копировать кажется лишними затратами.
.
> Но нам-то нужен был пример, где всё плохо и падает
.
Ну с таким подходом… можно любую концепцию «с дерьмом съесть» ©. Скандалы, интриги, расследования
.
Меня огорчает ровно обратное.
На купленном год назад, современном, планшете (intel, не ARM) я не могу поставить Windows 2000 со всеми нужными на сегодня исправлениями, и даже просто войти в интернет-банк заплатить за электричество.
.
> фото Full HD. А теперь могут прямо на страницу вставить 4K
.
… и у многих на телефонах оно отобразится 1:1? Телефоны по траффику уже обгоняют компьютеры.
.
Но сжимать фото компьютеры умели давно. Когда стали модными фильмы H.264 Full HD я поменял процессор. У меня был монитор 1600*1200, классических пропорций, и мне долго не хотелось покупать сплюснутые мониторы. Но Athlon 4200+ при сжатии Full HD до 1600 начал подтормаживать. Пришлось купить свеженький Phenom 710. Он у меня до сих пор.
.
Тем не менее, даже 4200+ успевал разбираться с видео Full HD, даже в самых напряженных сценах несколько раз в секунду. И один раз загрузить фото размером вдвое больше ему было бы по силам вполне.
.
Если в самом деле считать 4K картинки внутри обычных статей на обычном сайте преимуществом — то для него не нужно больше железа, чем 10 лет назад.
.
И фильмы Full HD mp4 старенький 4200+ мог показывать, и даже H.264 мог, если бы сжимать не приходилось. H.265 наверное не смог бы, пришлось бы мне страдать от H.264.
.
Вы же как-то обходитесь без фильмов сжатых в Dirac. Может быть у вас и кодека такого не установленно. Вам это как-то мешает?
.
Более того, еще два года назад Opera 12 была моим основным браузером и остается основным почтовиком. Ничего удобнее не придумали. И меня огорчает, что для того, чтобы тупо ввести логин-пароль на форум или в банк теперь обязательно под это окошко отдать гигабайт памяти.
.
И я еще помню NNTP форумы, которые выглядели не так, как хочет администратор сайта, а так, как хочет посетитель. И которые можно было читать-писать без постоянного подключения к интернету, с майнингом и стробоскопической рекламой внагрузку.
.
> Ну и софт тоже поднабрался умений.
.
Точно набрался, а не потерял?
.
> За последние 10 лет появился HTML 5, теперь можно писать приложения, работающие прямо в окне браузера.
.
Приложения — это вообще-то JS, а не HTML.
Но их и раньше можно было писать.
Даже и «в окне браузера» — Java, ActiveX.
.
> Хотя бы тот же Google Docs — вполне удобная штука.
.
Неплохая, если нужно одновременно исправлять одну и ту же табличку с разных континентов. Или хотя бы вставить ссылку в статью.
.
За исключением более простой публикации и одновременной работы, что такого нового научились таблицы Гугл, чего бы не умел Excel 97? А тем более — Excel 2010?
.
Вы же говорите, что «десятилетней давности» компьютеры плохи, потому что за эти 10 лет «софт научился» чему-ту очень новому и очень нужному.
.
Ну расскажите мне что же такого нового и очень нужного обычному человеку есть в Таблицах Гугл 2020, чего нет в Excel 2010 ?
.
> Но за это приходится платить потяжелевшим браузером.
.
С хрена ли нужно «платить» за возможность запустить Google Docs на всех остальных страницах???
И даже людям, которые не будут запускать Google Docs?
.
А вы посчитаете нормальным «платить» за какие-то мои новые привычки и удобства?
Захочу я, допустим, такси каждый день, ведь это удобно, к этому можно привыкнуть, как к 4K thumbnails, а вам — вам! — «нужно платить». Нормально?
.
> ходить с него по сделанным тогда сайтам
.
Вопрос не про «сделанные тогда», а про наполнение.
От того, что отломали поддержку старых браузеров наполнение сильно но изменилось. Всякие рекламные свистоперделки поменялись. А контент — тот же.
.
Что конкретно принципиально нового в контенте iXBT 2020, чего не было и не могло быть на iXBT 2010?
.
Ну почему же «мистическим», наверняка там куча незамеченных глюков, основанных на неявных предположениях. Линейки всегда деревянные, потому что я 10 лет в школе учился, и никогда других не было.
.
Я вот помню писал плагин к одной программе. И упоролся я сделать DLL размером 2KB. Практического смысла не было, просто прикола ради.
В частности пришлось выкинуть родной для языка менеджер кучи и использовать Windows'овский. И он таки какой-то медленный, да. В частности, надежности ради, при освобождении памяти он ее затирает.
… и тут-то хост программа начала падать. Оказалась, что она сначала освобождала буфер, а потом из него копировала данные. Типовая ошибка. Но на обычных, оптимизированных под скорость менеджерах — незаметная.
.
Возвращаясь к Хромиуму....
На вскидку, можно ли *предположить*, что при выделении подряд одинаковых блоков памяти — они подряд и лягут? А дальше всякая pointers mathematics для простого и быстрого обращения к item[n]. Строго по сишному определению, что массив == указатель.
Теперь смотрим на LFH и его рандомизацию, и особенно на внезапно включаемое и отключаемое распараллеливание (contention, affinity), и представляем item[n] вместо item_ptr[n]->.
.
И еще вопрос, а не занимается ли Хромиум иногда reallocate? Изменением размера ранее выделенного блока? В «тупом» менеджере это не поменяет адрес. Либо отказ, либо адрес прежний. А в LFH это сразу приводит к перемещению буфера в другую корзину. Привет, stalled pointers.
.
А могут ли там быть гонки между потоками? Когда один поток выделяет буфер и сохраняет его в новом объекте, а другой — объект использует. Если выделение — операция примитивная и быстрая, то успевает. А когда включается вся Goldberg machine с активациями корзин — не успевает.
.
И т.д.
А так — да, это проблема доступа из нативного кода к менеджед объектам, а не наоборот. Кстати, в нативном коде лет 20 назаж было так же, когда Apple OS или Windows приходилось запускать на 1-4 мегабайтах памяти. Тогла вообще не было указателей на объекты/массивы, а только хэндлы. Надо поработать — VirtualLock, а потом обратно. Apple OS потом на помойку выкинули, а вот VirtualLock в винде до сих пор остался для совместимости :)
Но я все равно не понимаю, за каким лешим мусорщику двигать массивы с value types (а массив реф-типов в C++ нафиг нужен). Это ж не объект, к которому все указатели на голову. Тут указатели можно и на внутренние элементы брать. Да и для скорости лучше без копирования массивов. Как-то это зря, лучше бы они для массивов простых типов делали отдельный сегмент кучи и не двигали вообще.
И если уж очень надо, то pin должен делаться автоматически внутри маршаллинга. Выносить этот бойлерплейт в код приложения — бред какой-то.
Я читал про него, из общего любопытства. Но поскольку на это не завязан, то все детали так же из любопытства и забыл.
Я ее и просматривал. Но… Там мало деталей, это ж Power Point. И вообще, полночь. Если всерьез, то надо брать коды других менеджеров кучи, сравнивать реализации там и что известно про МС… А это на несколько часов напряженной работы.
Это важно, потому что вопрос ставится «кто жрет память». Т.е. кто заказывает ее выделение, а не кто выполняет. А память почти наверняка в гугле жрет «вылизанный до блеска» JS, а не «тупой и примитивный» C++. Как и в фаерфоксе.
Это, конечно, не разбор самой кучи, но про нее в общих чертах рассказано.
Довольно любопытно, но возникает ощущение перегруженности.
Например, сегменты для маленьких блоков дополнительно делятся по размерам и иногда (но не всегда) по процессорам/ядрам. И после всего этого — еще и рандомизация при выборе свободного слота. А это же все не бесплатно...
Надо будет константы размеров сравнить с константами из FastMM4, интереса ради.