Pull to refresh

Comments 27

Прочитал половину статьи и думаю: что за бред, ведь в .NET все не так работает. Пролистал в поисках гневных комментариев и только тогда увидел тэг JAVA.
Ну так картинка как-бы намекает.
Да и что уже прям совсем не так работает? Чего греха таить, очень много из JAVA .NET позаимствовал.
В целом механизмы конечно похожи, но:

«GC в этом случае использует так называемое «молодое поколение» («young generation») — сегмент кучи, где размещаются новые объекты. Каждый объект имеет поле «возраст» («age», находится в заголовке объекта), который определяет сколько сборок мусора он пережил. Как только достигнут определенный возраст, объект копируется в другую область кучи, называемую «старым» («old») поколением.»

В .NET куче вместо молодого и старого поколений, есть поколения 0, 1 и 2. (http://msdn.microsoft.com/en-us/library/ee787088.aspx)

«Операторы, такие как „+“ при объединении строк в действительности создают новый объект String, содержащий конкатенацию строк. Ко всему прочему, это приводит к неявному созданию объекта StringBuilder, который и проводит саму операцию объединения.»

Для .NET это не верно. Объединение строк будет создавать новую строку в памяти без участия StringBuilder.

P.S.: Как я отстал от жизни, в первый раз увидел Duke.
В .NET куче вместо молодого и старого поколений, есть поколения 0, 1 и 2.

Не только new, young, old. Еще eden, tenured, perm gen, survivor spaces.
Хотелось бы еще добавить к статье, что конструктор по умолчанию ArrayList создаст массив из 10 элементов, а это лишнее потребление памяти в ряде случаев, опять же не в лучшую сторону влияющий на сборку мусора.
Какой ужас. Детский сад вперемешку с феерическим бредом.
Информативно. А можете развить свою мысль? Пока что ваш комментарий вида «Вы все дураки и не лечитесь».
UFO just landed and posted this here
По поводу 4 как раз не бред. Если надо закачать файл на сервер и сохранить его на диск то имеет смысл не считывать сначала все 500 mb файла в память, а потом сохранять на диск, а сразу брать входной стрим с файлом и кусками переписывать в выходной стрим файла. Мне кажется как раз об этом автор и говорил.
По поводу 5, я уверен что автор это прекрасно понимает. Совет да, немного очевидный вида, «если у вас очень плотная и частая рабрта с коллекциями, то имеет смысл возвращать изменяемые коллекции, чтобы не создавать зря новые». Но он нормпльный и имеет место быть.
Да тут сборище цитат. Претензии не к переводу, а к источнику.

«Долгая процедура сборки мусора может привести к явлению, известному как «Stop the world».» — а может и не привести. А быстрая приведет? А без stop the world можно? Блин — взялся писать — хоть узнай что к чему. В сети тонны правильных презентаций, на амазоне терабайты правильных книг.

«Сборщик мусора (Garbage Collector, GC) существует для обработки большого количества выделений памяти под короткоживущие объекты» — WAT? а долгоживующие как? Кстати что за выделения? Они не заразные?

«GC в этом случае использует так называемое «молодое поколение» («young generation») — сегмент кучи, где размещаются новые объекты. Каждый объект имеет поле «возраст» («age», находится в заголовке объекта), который определяет сколько сборок мусора он пережил. Как только достигнут определенный возраст, объект копируется в другую область кучи, называемую «старым» («old») поколением. » — врут сволочи. GC (абстрактный) работает совсем не так.

«Строки являются неотъемлемой частью практически любой структуры данных. Будучи более требовательными к ресурсам, чем другие примитивные типы» — WAT? Строка примитивный тип????? Назад в школу и не вылазить.

И т.д.
1. «Stop the world» тоже зацепило. Это способ работы определенных реализаций GC, а не побочный эффект.

2. «под короткоживущие объекты» — тут как-то криво пытаются объяснить, что работа GC основана на предположении, что подавляющее большинство объектов не переживает даже одну сборку => копирующая сборка мусора эффективна.

4. «other primitive values» — был уверен, что баг перевода.
«Не стреляйте в пианиста — он играет как умеет»
Смысл статьи — всего лишь дать пару советов Java-newbie.
Какой смысл давать бессмысленные советы?
Если не знаешь как там все работает — то такие советы вредны. А если знаешь — то не нужны.
А вредны во первых, потому что захламляют код, ну и во вторых — я на каждый «хинт» могу сделать контрпример, когда данный хинт будет вызывать деградацию. Кроме разве что первого «хинта», потому, что там какая-то невнятность, я никакого «хинта» не вижу.
1) С одной стороны правильный совет, с другой стороны не надо забывать про StringsPool, где JVM кэширует строки. Плюс строки часто используются в HashSet/HashMap, где надо высчитывать hashCode. Для строк это достаточно дорогая операция, поэтому как только один раз вызвался hashCode, то значение hashCode будет закэшировано. Поэтому если строки берутся из пула строк, то скорее всего хэшкод будет уже посчитан. Во вторых не надо забывать про то, что JVM бурно развивается, и многие вещи могут быть оптимизированны на этапе компиляции(к примеру теже конкатенации строк, могут быть заменены на StringBuilder) или внутри HotSpot'a. Так в новых версиях JVM, появилась такая замечательная штука как Escape Analysis. Почитать можно тут: elizarov.livejournal.com/29987.html
Escape Analysis позволяет создавать объекты в стэке, а не в heap'e.
2) совет правильный, но собрать массив для GC весьма легко, поэтому оверхэд не очень большой. Плюс ничего не сказано о том, что HashMap/HashSet имеют коэфицент расширения 0.75. Т.е. что бы создать Map c известной длинной, надо:
Map someMap = new HashMap((int) ((expected_maximal_number_of_data)/0.75+1));
3) имеет право на жизнь, но по той же Trove библиотеки, хоть приемущество и есть, но оно не столь существенно для небольших данных. Плюс опять же, как только JVM придумет какую-то оптимизацию — то вы будете иметь код, который не всегда просто переписать.
4) Убирать буфферизацию очень странный подход. Во первых собрать большой объект, который в памяти находится одним длинным отрезком очень легко, а вот реализовать иногда обработку стрима данных не так просто. Плюс буфферизация уменьшает блокировки IO, что весьма важно для большого количества IO в проекте. То же решение, которое предлагает автор — посути та же самая буфферизация, только она ограничена каким-то значением.
5) «We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil» by Donald Knuth.
Оптимизацией надо заниматься тогда, когда это требуется. Т.к. это ухудшает читаемость кода, а так же ведет к большому количеству ошибок.
Опять же смотрим на Escape Analysis.
Не стоит забывать, что строки иммутабельны. Они не модифицируются после аллокации. Операторы, такие как "+" при объединении строк в действительности создают новый объект String, содержащий конкатенацию строк.

Это у вас русский такой? Так нельзя было написать что ли?
Не стоит забывать, что строки неизменяемы. Они не изменяются после выделения памяти. Операторы, такие как «+» при объединении строк в действительности создают новый объект String, содержащий объединение строк.
На Хабре такой коммент можно писать к каждой первой статье. Скажите списибо, что не «immutable'ны».
IMHO, «immutable'ны» звучит лучше, чем «иммутабельны».
Хотя бы показывается, что влом переводить, и поэтому используется англоязычный термин.
А второй способ — просто издевательство над русским языком.
Статья вредная и непонятно для кого. Абсолютно каждый её совет сомнителен.

Складывается твёрдое ощущение, что она, если и основана на каком-то поведении какой-то джавы, то этой джаве лет 10.

Ну и это — стрингбилдер засирает код. Из внятного и очевидного он становится нечитаемым месивом аппендов. Каждый раз, когда вижу стрингбилдер — хочу переломать автору кода пальцы. Оптимизировать нужно по делу, а не всё подряд.
Я те переломаю! Ты просто не умеешь его готовить(с)

Хотя, когда вижу код типа
@Override
public String toString(){
     return new StringBuilder("value:").append(value).toString();
}

хочется сделать то же самое.
В целом нельзя не согласится с тобой — что почти каждый совет сомнителен и попахивает солепсизмом.

Возьмём хотя бы 3. Используйте эффективные коллекции примитивных типов — в целом совет имеет право на жизнь, но в очень очень специфичных задачах и при специфичных требованиях.
И для меня очень сомнительно, если пишется код с чистого листа, который использовать trove или ещё что без каких-то чётких причин.

Наверняка будет произведён какой-то нагрузочный тест или тест на производительность, и тыкнут пальцем на autoboxing и JCF.

Стоило бы переформулировать пункт как Используйте эффективные структуры данных и хотя он звучит как совет КО, но как раз разворачивая этот тезис можно рассказать и о побочных эффектах autoboxing, j.u.HashMap, об открытой адрессации, trove и других framework'ах.
Родные JDK-шные коллекции — это универсальный механизм, оптимизированный для общего случая. Безусловно, в каких-то специфических случаях замена коллекций поможет. Но действительно, завязываться на сторонние либы, не имея на то веских причин, я бы не стал.
4 — явно вредный совет. Буферизация придумана в Java не просто так, а чтобы уменьшить количество обращений к native методам. Если читать из потока без буфера, каждый прочитанный байт вызовет дополнительную задержку www.javamex.com/tutorials/jni/overhead.shtml

5 — еще более вредный совет. В случае многопоточного приложения ArrayList использовать нельзя docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html
В случае же синхронизированного списка многопоточность вырождается в один поток (т.к. все потоки будут ждать своей очереди на добавление в список)
4 — никто ничего не читает тут. Автор сказал, что если у вас есть у десериализатора есть 2 метода: deserialize(byte[] data) и deserialize(InputStream stream) и если у вас есть InputStream например файла, то имеет смысл не вычитывать ВЕСЬ файл в массив байтов и только потом отдавать десериализатору. А лучше сразу отдать ему InputStream. Думаю, что разработчики библиотек не все идиоты и не будут считывать по 1 байту, как вы тут написали.

5 — да вы издеваетесь. Автор явно написал, что неизменяемость не всегда благо. Т.е. он понимает, что неизменяемость в большинстве случаев — это хорошо. И я уверен, он прекрасно понимает, что это особенно хорошо для многопоточных приложений. А если у вас есть какая-то однопоточная операция с плотной работой с коллекциями, ВСЕГДА работающая в рамках 1 потока, то есть смысл использовать только ArrayList и не париться с Collections.unmodifableList. Но опять же всегда.
Автор сказал, что если у вас есть у десериализатора есть 2 метода

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

Т.е. он понимает

Быть может, после тяжелой рабочей неделе я немного растерял свои телепатические способности, ибо никак не смог узнать, что же автор понимает. Выводы я могу делать только по статье, в которой написано, цитирую: «Например, в случае когда коллекции, возвращенные из методов, собираются в окончательную коллекцию». Эту фразу нужно уточнить — в случае однопоточного метода.
Наверное, у меня глаза замылились перед выходными. Покажете точную цитату, из которой вы сделали такой вывод?

Да, автор этого конкретно не сказал. Вывод я такой сделал из фразы:
Многие библиотеки, такие как нативный сериализатор Java, Protocol Buffers и т.д. способны строить десериализованные объекты, используя данные напрямую из сетевого потока, т.е. не требуют хранения данных в памяти и внутренних массивах.


Эту фразу нужно уточнить — в случае однопоточного метода.

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

А если статья для профи — опять же, можно меньше воды и больше конкретики с пруф-линками. А так ни то ни се. Либо отсутствует глубина понимания, и не следовало писать статью, либо автор не умеет последовательно и полно излагать мысль — тогда имеет смысл доработать с учетом комментариев.

И еще совет автору статьи: указывайте в начале статьи вашу целевую аудиторию! Избавите себя от кучи негатива :-)
Sign up to leave a comment.

Articles

Change theme settings