Сколько памяти занимает boolean в java
Перейти к содержимому

Сколько памяти занимает boolean в java

  • автор:

Java/Типы данных

В Java есть 8 примитивных типов, которые делят на 4 группы, вот они:

  1. Целые числа — byte, short, int, long
  2. Числа с плавающей точкой (иначе вещественные) — float, double
  3. Логический — boolean
  4. Символьный — char

Целочисленные типы [ править ]

Целочисленные типы различаются между собой только диапазонами возможных значений, например, для хранения номера элемента в таблице Менделеева пока хватит переменной типа byte.

Тип Размер (бит) Диапазон
byte 8 бит от -128 до 127
short 16 бит от -32768 до 32767
char 16 бит беззнаковое целое число, представляющее собой символ UTF-16 (буквы и цифры)
int 32 бит от -2147483648 до 2147483647
long 64 бит от -9223372036854775808L до 9223372036854775807L

Пример использования целочисленных типов:

public class IntegralTypes  public static void main(String[] args)  byte b = 216; // Вот тут будет ошибка, т.к. у нас диапазон от -128 до 127! short s = 1123; int i = 64536; long l = 2147483648L; // Постфикс l или L обозначает литералы типа long System.out.println(i); System.out.println(b); System.out.println(s); System.out.println(l); > > 

Символы тоже относят к целочисленным типам из-за особенностей представления в памяти и традиций.

public class Characters  public static void main(String[] args)  char a = 'a', b, c = 'c'; b = (char) ((a + c) / 2); // Можно складывать, вычитать, делить и умножать // Но из-за особенностей арифметики Java результат приходится приводить к типу char явно System.out.println(b); // Выведет символ 'b' > > 

Типы с плавающей точкой [ править ]

Тип Размер (бит) Диапазон
float 32 от 1.4e-45f до 3.4e+38f
double 64 от 4.9e-324 до 1.7e+308
public class FloatingPointTypes  public static void main(String[] args)  double a, b = 4.12; a = 22.1 + b; float pi = 3.14f; // При использовании типа float требуется указывать суффикс f или F // так как без них типом литерала будет считаться double float anotherPi = (float) 3.14; // Можно привести явно double c = 27; double d = pi * c; System.out.println(d); > > 

Логический тип [ править ]

Тип Размер (бит) Значение
boolean 8 (в массивах), 32 (не в массивах используется int) true (истина) или false (ложь)

В стандартной реализации Sun JVM и Oracle HotSpot JVM тип boolean занимает 4 байта (32 бита), как и тип int. Однако, в определенных версиях JVM имеются реализации, где в массиве boolean каждое значение занимает по 1-му байту.

Ссылочные [ править ]

Ссылочные типы — это все остальные типы: классы, перечисления и интерфейсы, например, объявленные в стандартной библиотеке Java, а также массивы.

Строки [ править ]

Строки это объекты класса String, они очень распространены, поэтому в некоторых случаях обрабатываются отлично от всех остальных объектов. Строковые литералы записываются в двойных кавычках.

public class Strings  public static void main(String[] args)  String a = "Hello", b = "World"; System.out.println(a + " " + b); // Здесь + означает объединение (конкатенацию) строк // Пробел не вставляется автоматически // Строки конкатенируются слева направо, надо помнить это когда соединяешь строку и примитив String c = 2 + 2 + ""; // "4" String d = "" + 2 + 2; // "22" d = "" + (2 + 2); // а теперь d тоже "4" String foo = "a string"; String bar = "a string"; // bar будет указывать на тот же объект что и foo String baz = new String("a string"); // Чтобы гарантированно создать новую строку надо вызвать конструктор System.out.println("foo == bar ? " + (foo == bar)); // == сравнивает ссылки на объекты System.out.println("foo равен bar ? " + (foo.equals(bar))); // Метод equals служит для проверки двух объектов на равенство System.out.println("foo == baz ? " + (foo == baz)); System.out.println("foo равен baz ? " + (foo.equals(baz))); > > 

Эта программа выведет:
Hello World
foo == bar ? true
foo равен bar ? true
foo == baz ? false
foo равен baz ? true

Обертки [ править ]

Если требуется создать ссылку на один из примитивных типов данных, необходимо использовать соответствующий класс-обертку. Также в таких классах есть некоторые полезные методы и константы, например минимальное значение типа int можно узнать использовав константу Integer.MIN_VALUE. Оборачивание примитива в объект называется упаковкой (boxing), а обратный процесс распаковкой (unboxing).

Тип Класс-обертка
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double
boolean Boolean
int i; Integer boxed; // Обычное создание объекта boxed = new Integer(i); // Фабричный метод boxed = Integer.valueOf(i); // Автоматическая упаковка, компилятор просто вставит вызов Integer.valueOf boxed = i; 

Рекомендуется использовать valueOf, он может быть быстрее и использовать меньше памяти потому что применяет кэширование, а конструктор всегда создает новый объект.

Получить примитив из объекта-обертки можно методом Value.

Integer boxed; int i; // Явная распаковка i = boxed.intValue(); // Автоматическая распаковка i = boxed; 

Размер типа boolean

Для всех примитивных типов данных, кроме типа boolean , в Java однозначно определен размер. Размер типа boolean , насколько я понимаю, зависит от реализации конкретной виртуальной машины. Вопрос: почему для типа boolean однозначно не определили размер?

Отслеживать
задан 8 фев 2017 в 23:39
417 1 1 золотой знак 4 4 серебряных знака 11 11 бронзовых знаков

Встречный вопрос. А с какими целями это, по-вашему, может быть надо? Полагаю, что ответ «определять размер однозначно было просто незачем» вас не устроит.

– user181100
8 фев 2017 в 23:48
@D-side, Это же ровно то, что я спрашиваю.
8 фев 2017 в 23:50

Потому что boolean — 1 бит. А адресовать один бит нельзя. А количество бит/байт которые можно адресовать (читай, минимальный размер памяти, который можно прочитать) в теории зависит от реальной машины, на которой исполняется java. Думаю причина в этом.

8 фев 2017 в 23:53

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

А зачем? Языку не должно быть до этого дела.

Если поведение однозначно определено, всё остальное вторично.

Тип boolean прекрасно определяется множеством своих допустимых значений. Математически оно ограничивает минимальный размер значения одним битом.

Но использовать именно один бит (и ни битом более) эффективно далеко не всегда, поскольку на популярных архитектурах нельзя адресовать отдельные биты. А потому значения отдельных boolean ‘ов нельзя быстро сохранить в отдельные биты оперативной памяти — необходимо использовать комбинацию побитовых операций, что почти наверняка будет медленнее, чем запись целого отдельного регистра в оперативную память (размер которого может быть различным на разных платформах!).

Но при этом, к примеру, я вполне себе представляю, как на x86 компилятор может использовать в нативном коде в качестве какого-нибудь конкретного boolean -значения один бит регистра флагов, при условии, что это значение никогда не попадает в оперативную память (отдельно от других). Поэтому любые ограничения на размер более одного бита тоже могут потенциально мешать.

И эта свобода представления позволяет авторам виртуальных машин Java использовать любые реализации, которые они считают наиболее эффективными в каждом конкретном контексте. Как видно из примеров выше, любые ограничения будут только мешать.

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

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

К слову сказать, сделай я правильный backup и экстренные работы по восстановлению жизнеспособности прошли бы гораздо более спокойно, но это была бы уже совсем другая история. Итак в моём распоряжении есть код, которому не хватает 15Gb оперативной памяти для нормального функционирования и очень длительный и дорогостоящий процесс запуска (около 5 часов), в ходе работы которого можно только сидеть со скрещенными пальцами и надеятся, что в этот раз заветные слова OutOfMemoryException не появятся в консоли удалённого сервера.
Не буду описывать всех ухищрений, которые пришлось проделать, чтобы восстановить остановленный сервер в течении трёх дней, но одним своим мини открытием поделюсь — boolean — это не тот тип данных, который Вы хотите использовать в высоконагруженных системах. Внимание вопрос:

Как Вы думаете, сколько памяти занимает boolean например на Ubuntu server x64?

Правильным ответом будет: неизвестно и зависит только от реализации JVM.

Рассмотрим распространённую Sun JVM и прочтем в спецификации виртуальной машины, что boolean типа в ней нет как такового, вместо него используется int! А это означает, что для хранения значения типа «да\нет» используется ровно 32 бита, независимо от архитектуры процессора. Правда в том же разделе мы видим, что произведена оптимизация для работы с массивами boolean, которые преобразуются в массив байт, что даёт прирост доступной памяти в 4 раза. И всё же платить за хранение нолика или еденички семью лишними битами — иногда просто кощунство и издевательство над серверами (особенно при размерах массивов в 500 миллионов элементов).

Спасением в таких случаях будет класс BitSet, который ведёт себя подобно массиву boolean, но упаковывает данные так, что для одного бита выделяется всего один бит памяти (с небольшими издержками для всего массива). BitSet хранит внутри себя массив типа long, а при запросе или установке значения определенного бита — высчитывает индекс нужного long и пользуясь побитовыми операциями и операциями сдвига производит вычисления над единственным битом.
Существует еще более интересная реализация BitSet, OpenBitSet — Apache реализация, которая используется для Lucene. Она гораздо быстрее, но упускает некоторые проверки, проводимые в оригинальном BitSet. Что использовать — решать Вам.

Какой объём памяти занимает переменная типа boolean? 1 байт; 2 байта; 8 байт; 4 байта; 1 бит.

Bool может принимать только два значения: 1 или 0, правда или ложь. По-сути — это 1 бит, но реальный объем занимаемой памяти будет скорее 1 байт, т. к. меньше 1 байта не может быть адресовано.

зависит от яп.

Похожие вопросы

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *