Pull to refresh
9
0
Максим Боговик @maxBogovick

User

Send message

Размер Java объектов

Reading time5 min
Views188K
Знаете сколько в памяти занимает строка? Каких только я не слышал ответов на этот вопрос, начиная от «не знаю» до «2 байта * количество символов в строке». А сколько тогда занимает пустая строка? А знаете сколько занимает объект класса Integer? А сколько будет занимать Ваш собственный объект класса с тремя Integer полями? Забавно, но ни один мой знакомый Java программист не смог ответить на эти вопросы… Да, большинству из нас это вообще не нужно и никто в реальных java проектах не будет об этом думать. Но это, ведь, как не знать объем двигателя машины на которой Вы ездите. Вы можете быть прекрасным водителем и даже не подозревать о том, что значат цифры 2.4 или 1.6 на вашей машине. Но я уверен, что найдется мало людей, которые не знакомы со значением этих цифр. Так почему же java программисты так мало знают об этой части своего инструмента?

Integer vs int

Все мы знаем, что в java — everything is an object. Кроме, пожалуй, примитивов и ссылок на сами объекты. Давайте рассмотрим две типичных ситуации:
//первый случай
int a = 300;
//второй случай
Integer b = 301;

В этих простых строках разница просто огромна, как для JVM так и для ООП. В первом случае, все что у нас есть — это 4-х байтная переменная, которая содержит значение из стека. Во втором случае у нас есть ссылочная переменная и сам объект, на который эта переменная ссылается. Следовательно, если в первом случае мы определено знаем, что занимаемый размер равен:
sizeOf(int)

то во втором:
sizeOf(reference) + sizeOf(Integer)

Забегая вперед скажу — во втором случае количество потребляемой памяти приблизительно в 5 раз больше и зависит от JVM. А теперь давайте разберемся, почему разница настолько огромна.

Из чего же состоит объект?

Прежде чем определять объем потребляемой памяти, следует разобраться, что же JVM хранит для каждого объекта:
  • Заголовок объекта;
  • Память для примитивных типов;
  • Память для ссылочных типов;
  • Смещение/выравнивание — по сути, это несколько неиспользуемых байт, что размещаются после данных самого объекта. Это сделано для того, чтобы адрес в памяти всегда был кратным машинному слову, для ускорения чтения из памяти + уменьшения количества бит для указателя на объект + предположительно для уменьшения фрагментации памяти. Стоит также отметить, что в java размер любого объекта кратен 8 байтам!

Читать дальше →
Total votes 118: ↑107 and ↓11+96
Comments39

Сравнение потребления памяти у разных структур хранения данных

Reading time2 min
Views25K
Различные структуры в Java потребляют разное количество памяти. Поэтому для нас очень важен выбор наиболее эффективного метода хранения данных.

Какая будет разница по потреблению памяти между конструкциями `new int[1024]` и `new Integer[1024]`?

int[] ints = new int[1024];
for (int i = 0; i < ints.length; i++) ints[i] = i;

Integer[] ints = new Integer[1024];
for (int i = 0; i < ints.length; i++) ints[i] = i;

Узнать
Total votes 50: ↑41 and ↓9+32
Comments43

boolean — боремся за Java память…

Reading time2 min
Views35K
У Вас когда-либо случались такие ситуации, когда Ваше Java приложение трещит по швам? В моём случае это случилось из-за нехватки доступной оперативной памяти. И, естественно, обнаружилась нехватка в самый неподходящий момент: на носу очередной долгожданный релиз, один из серверов остановлен для обновления кода и данных и реинкарнация старого кода уже невозможна, в ближайшие дни запланировано несколько совещаний и собеседований, что сильно отвлекает от процесса оптимизации — в общем, ЧП не прошло незамеченным.

К слову сказать, сделай я правильный backup и экстренные работы по восстановлению жизнеспособности прошли бы гораздо более спокойно, но это была бы уже совсем другая история. Итак в моём распоряжении есть код, которому не хватает 15Gb оперативной памяти для нормального функционирования и очень длительный и дорогостоящий процесс запуска (около 5 часов), в ходе работы которого можно только сидеть со скрещенными пальцами и надеятся, что в этот раз заветные слова OutOfMemoryException не появятся в консоли удалённого сервера.
Не буду описывать всех ухищрений, которые пришлось проделать, чтобы восстановить остановленный сервер в течении трёх дней, но одним своим мини открытием поделюсь — boolean — это не тот тип данных, который Вы хотите использовать в высоконагруженных системах. Внимание вопрос:
Как Вы думаете, сколько памяти занимает boolean например на Ubuntu server x64?
Total votes 108: ↑88 and ↓20+68
Comments140

Сон и продуктивная деятельность

Reading time8 min
Views106K

Вступление


Доброго времени суток, %habrauser%! Думаю, в этой статье я не открыл ничего нового. Просто меня самого заинтересовала тема продуктивного сна. Несколько последних лет я был приверженцем мнения, что сон – это бесполезная трата времени, к сожалению необходимая организму. И посему, я максимально старался сократить время сна. Но чем больше я это делал, тем больше я начинал походить на зомби. И тогда я стал искать альтернативу. И результатом обобщения всей найденной мной информацией и стала эта статья. Итак, поехали!
Читать дальше →
Total votes 243: ↑215 and ↓28+187
Comments149

И снова про сортировки: выбираем лучший алгоритм

Reading time9 min
Views143K
Недавно на хабре в очередной подняли тему алгоритмов сортировки, а именно был хорошо описан метод Timsort.

Он, имея сложность не более O(n log n), ускоряется в случае сортировки частично упорядоченных данных и имеет сложность O(n), если данные изначально отсортированны. Но это не единственный алгоритм с такими заявленными свойствами. Существует еще как минимум два более-менее известных метода с похожей сложностью — это Smoothsort и сортировка Шелла.

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

Читать дальше →
Total votes 117: ↑114 and ↓3+111
Comments32

Введение в MVP GWT 2.1

Reading time11 min
Views21K
Когда я писал топик об использовании шаблона Command для организации RPC-вызовов в GWT то упоминал об MVP-паттерне для построения архитектуры GWT-проектов. Сразу после выступления товарища Ray Rayan’а с докладом о проектировании сложных приложений на GWT трудящиеся по всему миру принялись реализовывать озвученные идеи в виде библиотек и фреймворков. Результатом этих трудов стали средства, позволяющие применять как некоторые моменты MVP-подхода (GWT-Presenter) так и его целиком (Mvp4G). Это все замечательно, но мне лично (уверен, что и остальным GWT-разработчикам) хотелось бы иметь стандартизированный (если можно так сказать) фреймворк/подход для организации GWT-приложений по MVP-схеме. И вот команда, которая отвечает в Google за GWT, наконец-то в версии 2.1 наряду с остальными вкусными плюшками предложила встроенный MVP-фреймворк.
В данной заметке я постараюсь осветить основные моменты встроенного GWT MVP-фреймворка. Как пример будет использовано небольшое приложение, построенное с применением этого подхода.
Данная заметка является вольным трактатом (GWT MVP Development) и на уникальность подхода никоим образом не претендует. Если кого-то заинтересовало такое немаленькое введение
прошу под хабракат!
Total votes 13: ↑9 and ↓4+5
Comments10

Подготовка к экзамену Oracle Certified Professional Java Programmer — Часть 1

Reading time8 min
Views57K

Предисловие



Хочу продолжить делиться приобретенными знаниями и своими впечатлениями от подготовки к экзамену. Огромное спасибо всем тем, кто дал рекомендации к нулевой части этой серии! Сегодня я поговорю еще немножко о модификаторах доступа и их взаимоотношениях с наследованием и пакетами, рассмотрю varargs и перечисления, а также массивы и способы их инициализации. Я надеюсь, что хабражители снова откликнутся и дополнят то, о чем я забыл упомянуть или попросту не знал.

Продолжаем готовиться к экзамену под катом.

Читать дальше →
Total votes 45: ↑38 and ↓7+31
Comments30

Структуры данных в картинках. LinkedList

Reading time4 min
Views544K
Приветствую вас, хабражители!

Продолжаю начатое, а именно, пытаюсь рассказать (с применением визуальных образов) о том как реализованы некоторые структуры данных в Java.



В прошлый раз мы говорили об ArrayList, сегодня присматриваемся к LinkedList.

LinkedList — реализует интерфейс List. Является представителем двунаправленного списка, где каждый элемент структуры содержит указатели на предыдущий и следующий элементы. Итератор поддерживает обход в обе стороны. Реализует методы получения, удаления и вставки в начало, середину и конец списка. Позволяет добавлять любые элементы в том числе и null.

Прочитать чуть больше
Total votes 50: ↑46 and ↓4+42
Comments22

Структуры данных в картинках. ArrayList

Reading time3 min
Views873K
Приветствую вас, хабралюди!

Взбрело мне в голову написать несколько статей, о том как реализованы некоторые структуры данных в Java. Надеюсь, статьи будут полезны визуалам (картинки наше всё), начинающим java-визуалам а также тем кто уже умеет писать new ArrayList(), но слабо представляет что же происходит внутри.



Сегодня поговорим о ArrayList-ах

ArrayList — реализует интерфейс List. Как известно, в Java массивы имеют фиксированную длину, и после того как массив создан, он не может расти или уменьшаться. ArrayList может менять свой размер во время исполнения программы, при этом не обязательно указывать размерность при создании объекта. Элементы ArrayList могут быть абсолютно любых типов в том числе и null.

Поверить на слово
Total votes 89: ↑82 and ↓7+75
Comments66

Плохая Java или как не надо делать

Reading time5 min
Views66K
Во время работы мне, как, наверное, и каждому из Вас, иногда приходится замечать мелкие недочеты Java. Маленькие и редкие, но присущие. К написанию этой статьи меня подвиг один из комментариев к моему первому посту. Тема показалась мне очень интересной и я решил припомнить все то, что мне не нравится в моем любимом языке программирования. Итак, начнем:

HashSet

Не знаю почему было принято такое решение, но HashSet реализован на HashMap, да — сэкономили время на создание, но это же одна из основных коллекций, почему к ее созданию не подошли более ответственно — не понятно. Всё-таки, можно было создать HashSet более оптимально. HashMap несет излишнюю архитектуру в контексте задач HashSet. Например, внутри HashSet есть следующий код:
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

Это значит, что любое ваше значение внутри HashSet будет ассоциироваться со ссылкой на этот обьект. Это тоже самое, что:
Map.put(key, PRESENT);

Казалось бы, подумаешь — 8 байт, который будут использоваться всеми. Но не забывайте что при каждой вставке в HashSet, создается Map.Entry, в котором 4 ссылки (еще 16 лишних байт на каждый элемент). Расточительно, не находите? Почему так? Большая загадка… Спасибо хоть не унаследовались.

Default logger

Кто в проекте не использует log4j? А можете сходу назвать библиотеки, которые тоже обходятся без него? Думаю это трудные вопросы. Понимаю, java не может подстраиваться под каждую конкретную задачу, но добавили же стандартный Logger, так почему за 10 лет существования log4j, java так и не взяла лучшее из него? Представьте на сколько бы уменьшились все приложения, особенно сложные, где в конечной сборке может оказаться несколько разных версий логера.
Читать дальше →
Total votes 85: ↑51 and ↓34+17
Comments87

Как работает ConcurrentHashMap

Reading time5 min
Views165K
В октябре на хабре появилась замечательная статья про работу HashMap. Продолжая данную тему, я собираюсь рассказать о реализации java.util.concurrent.ConcurrentHashMap.
Итак, как же появился ConcurrentHashMap, какие у него есть преимущества и как он был реализован.
Читать дальше →
Total votes 105: ↑100 and ↓5+95
Comments14

Секреты JDK

Reading time4 min
Views25K

Про Unsafe в Java не слышал только ленивый, однако это не единственный магический класс в Sun/Oracle JDK, стирающий границы Java платформы и открывающий тропинки, не нанесенные на карту публичного API. Я расскажу про некоторые из них, принесшие пользу в реальных проектах. Но помните: недокументированные возможности лишают ваше приложение переносимости на другие Java платформы и, кроме того, являются потенциальным источником нетривиальных ошибок. Я даже зря написал слово «приложение». Лучше сказать, что описанные ниже классы вовсе не годятся для приложений! Скорее, они представляют интерес лишь для системного ПО и для любознательных программистов, т.е. для вас :)
Читать дальше →
Total votes 129: ↑127 and ↓2+125
Comments30

Свое представление (view) в Spring MVC

Reading time5 min
Views16K
Если вы работали с Spring MVC то наверняка обращали внимание, что он поддерживает множество различных представлений (view), которые позволяют генерировать pdf, excel, csv использовать jstl, freemarker, velocity и jasperReports. Но что делать если вам потребовалось заполнить какой либо документ в формате docx по шаблону и передать его пользователю? С одной стороны можно в методе воспользоваться доступом к стандартному response и если планируется использовать такую генерацию множество раз, то вынести ее в отдельный класс. Но такое решение не слишком изящно и нарушает MVC-паттерн.
Что можно сделать чтобы этого не происходило?
Total votes 20: ↑19 and ↓1+18
Comments20

Учимся готовить: Spring 3 MVC + Spring Security + Hibernate

Reading time12 min
Views354K
Добрый день! Меня зовут Антон Щастный.

Это моя очередная статья, посвящённая разработке веб приложений на Java. Хочу предложить вам сделать небольшую систему учёта клиентов, написанную с использованием фреймворка Spring и библиотеки Hibernate.

Что будет в приложении:


Будет простой менеджер контактов, позволяющий добавлять в базу новые записи, просматривать имеющиеся, удалять ненужные. Сведения будут храниться в базе данных. Доступ к приложению – через веб, с аутентификацией и авторизацией пользователей.

Что будем использовать:


  • веб фреймворк Spring MVC,
  • фреймворк Spring Security,
  • ORM библиотеку Hibernate,
  • MySQL в качестве СУБД.

Инфраструктура:
  • редактор SpringSource Tool Suite,
  • сборщик проектов Maven,
  • система логгирования Log4j,
  • постоянное подключение к интернету.


В моей предыдущей статье о Spring MVC был упущен ряд моментов по использованию аннотаций в Java-коде и применению Maven для сборки проекта. В данной статье я попытался исправить упущение.

Цель статьи – показать начинающим веб разработчикам совместное использование различных технологий платформы Java.

Читать дальше →
Total votes 43: ↑41 and ↓2+39
Comments52

Создание своих архетипов и каталогов в Maven

Reading time8 min
Views34K
Уже довольно продолжительное время (около года набежит) активно пользуюсь системой сборки Apache Maven и вполне ею доволен. Несмотря на свои очевидные и не очень недостатки, неоспоримым преимуществом является автоматическое управление зависимостями, хорошая структурированность проектов и отсутствие скриптов сборки как таковых, а следовательно проблем с ними.

Многим может не нравится, что мавен в самом деле отбирает у разработчика свободу выбора структуры проекта и прямо таки диктует ее, но в самом ли деле эта свобода настолько важна, чтобы делать изза нее жирный аргумент против? Не думаю. Есть другие, более серьезные, на мой взгляд, недостатки, в первую очередь — трудность диагностики проблем при сборке и недостаточная документированность мавена и плагинов.
Читать дальше →
Total votes 37: ↑33 and ↓4+29
Comments17

Вторая жизнь вместе с Maven

Reading time17 min
Views83K
Думаю, для большинства хабражителей не будет откровением, что среди крупных софтварных разработок нередко встречаются технологии и языки значительно отстающие от передовых. К сожалению, это неизбежность, т. к. невозможно в какой-то момент взять и переписать несколько миллионов строк кода на другой язык или с применением более современного фреймворка.

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

Здесь я хочу рассказать о том, как в конкретном случае я постарался оттянуть неизбежное и оживить разработку применив для этого сборщик проектов Maven.

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

Читать дальше →
Total votes 5: ↑5 and ↓0+5
Comments3

Типичные случаи утечки памяти в Java

Reading time4 min
Views74K
Большинству разработчиков известно, что сборщик мусора в Java не является универсальным механизмом, позволяющим программисту полностью забыть о правилах использования памяти и о том, в каких случаях осуществляется его работа. Ниже описаны типичные случаи утечки памяти в java-приложениях, встречающиеся повсеместно.
Итак, о чём должен помнить каждый java-программист.
Читать дальше →
Total votes 113: ↑104 and ↓9+95
Comments80

Маленькие хитрости Java. Часть 2

Reading time5 min
Views108K
В продолжение первой статьи я добавлю еще несколько штрихов о наиболее часто встречающихся ошибках и просто плохом коде, с которым часто приходится иметь дело при работе с уже написанными проектами. Я не выносил это в первую часть, так как эти ситуации встречаются гораздо реже, но поскольку первая часть вызвала много позитивных отзывов, решил продолжить. Спасибо всем комментаторам, отзывам и замечаниям. Я постараюсь избежать допущенных ошибок. Итак, продолжим:

Buffered Streams

//медленно
InputStream is = new FileInputStream(file);
int val;
while ((val = is.read()) != -1) {
}
//быстро
InputStream is = new BufferedInputStream(new FileInputStream(file));
int val;
while ((val = is.read()) != -1) {
}

Казалось бы — очевидная истина, неправда ли? Но как показал чужой код и опыт собеседования кандидатов, часть разработчиков определенно не понимает в чем преимущество буферизованных стримов. Кто до сих пор не разобрался — метод read() класса FileInputStream:
public native int read() throws IOException;

Согласитесь, каждый раз делать системный вызов, чтобы считать один байт несколько расточительно. Собственно для того, чтобы избежать этой проблемы и были созданы оболочки-буферы. Все что они делают — при первом вызове системного read() считывают несколько больше (в зависимости от указанного размера буфера, котрый по умолчанию равен 8 кб) и при следующем вызове read() считывают данные уже из буфера. Прирост производительности — на порядок. Системные вызовы, на самом деле, это не всегда плохо, например:
System.arraycopy(src, srcPos, dest, destPos, length);

В случае копированния массива — системный метод будет гораздо быстрей реализованного на java. И еще — считывайте данные порциями, а не по байтам, это тоже позволит прилично сэкономить.
Читать дальше →
Total votes 93: ↑84 and ↓9+75
Comments91

Маленькие хитрости Java

Reading time4 min
Views270K
Я уже достаточно много лет занимаюсь разработкой на java и повидал довольно много чужого кода. Как это не странно, но постоянно от одного проекта к другому я вижу одни и те же проблемы. Этот топик — попытка ликбеза в наиболее часто используемых конструкциях языка. Часть описанного — это довольно банальные вещи, тем не менее, как показывает мой опыт, все эти банальности до сих пор актуальны. Надеюсь, статья пригодится многим java программистам. Итак, поехали:

new vs valueOf

//медленно
Integer i = new Integer(100);
Long l = new Long(100);
String s = new String("A");

//быстро
Integer i = Integer.valueOf(100);
Long l = 100L;//это тоже самое что Long.valueOf(100L);
String s = "A";


Старайтесь всегда использовать метод valueOf вместо конструктора в стандартных классах оболочках примитивных типов, кроме случаев, когда вам нужно конкретно выделить память под новое значение. Это связано с тем, что все они, кроме чисел с плавающей точкой, от Byte до Long имеют кеш. По умолчанию этот кеш содержит значения от -128 до 127. Следовательно, если ваше значение попадает в этот диапазон, то значение вернется из кеша. Значение из кеша достается в 3.5 раза быстрее чем при использовании конструктора + экономия памяти. Помимо этого, наиболее часто используемые значения могут также быть закэшированы компилятором и виртуальной машиной. В случае, если ваше приложение очень часто использует целые типы, можно увеличить кеш для Integer через системное свойство «java.lang.Integer.IntegerCache.high», а так же через параметр виртуальной машины -XX:AutoBoxCacheMax=<size>.
Читать дальше →
Total votes 141: ↑126 and ↓15+111
Comments166

Паттерн проектирования «Команда» / «Command»

Reading time4 min
Views81K
Почитать описание других паттернов.
A

Проблема


Необходимо иметь эффективное представление запросов к некоторой системе, не обладая при этом знаниями ни об их природе ни о способах их обработки.

Описание


Существует по крайней мере три мотивации к использованию шаблона “Команда”:
  • инкапсулирование запроса в виде объекта для последующего протоколирования/логирования и т.п.
  • наделение сущности “вызов метода объекта” свойствами самостоятельного объекта;
  • объектно-ориентированный обратный вызов (callback);

Читать дальше →
Total votes 50: ↑42 and ↓8+34
Comments18

Information

Rating
Does not participate
Location
Тирасполь, Молдова, Молдова
Date of birth
Registered
Activity