What is the bit depth of a boolean in java? [duplicate]
Someone asked me a question, but I didnt get the question properly. is it related to size? If yes what’s the answer?
Been answered many times, here’s the first result from searching for «boolean size»: stackoverflow.com/questions/1907318/…
6 Answers 6
boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its «size» isn’t something that’s precisely defined.
in java, a boolean is 32 bits. Even though it really only is a single bit (0 or 1), its treated as an int .
Java Byte Code does not have a datatype ‘boolean’, therefore boolean primitives are converted to integer (32 bit) (except boolean arrays, where a boolean value is represented by a bit).
Does that mean that int s are as fast and memory efficient as boolean s in Java when not used in an array?
The answer is «JVM specific»
A boolean represents one bit of information.
How it is stored (whether one boolean per memory word, or packed with other boolean values in a single word, or in some radically different way that takes up 1000 bytes per boolean) is up to the JVM, as long as the other JLS provisions for primitive types are met.
It is probable the expression «bit depth» refer to the «number of bits per XXX» (here «number of bit(s) per boolean), as it does for pictures (x bits per data pixels).
Each pixel of an 8 bit image is describe in one of a possible 256 tones or colors.
Each pixel of a 24 bit image is describe in one of a possible 16.7 million tones or colors.
The higher the ‘bit depth’ of the image the greater the color or tonal quality.
I guess the actual size in memory depends on the JVM, but in theory a boolean can be represented as a 1 or 0 (1 bit).
A boolean is a true or false value, and can be stored in a lonely, single bit of memory. But the exact requirements are not outlined in the spec, and some operating systems cannot write to a bit, but minimally, to a byte, so a byte might end up being used by default, even thout only a bit is required.
«The bit depth» may relate to how much values a boolean can take. In most languages, it can take two values: true or false . In object oriented languages, if a boolean is an object (like Boolean in Java), the value can also be null (and some languages, apart from null, support a state called uninitialized, which can mean any value).
The size of the boolean in memory is an entirely different question. As already mentioned, for Java it is undefined, and if I recall correctly, it will likely depend on the WORD size of the system the program runs on. Theoretically, a boolean can be one bit in size, but only when we need many booleans, we can use that (called flags variables), because we are bound to the WORD boundaries of any system.
The size in the compiled image can be different again (in the event of constants), but you normally shouldn’t need to worry about that.
Linked
Related
Hot Network Questions
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.21.43541
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Размер Java объектов. Используем полученные знания
В предыдущей статье много комментаторов были не согласны в необходимости наличия знаний о размере объектов в java. Я категорически не согласен с этим мнением и поэтому подготовил несколько практических приемов, которые потенциально могут пригодится для оптимизации в Вашем приложении. Хочу сразу отметить, что не все из данных приемов могут применяться сразу во время разработки. Для придания большего драматизма, все расчеты и цифры будут приводится для 64-х разрядной HotSpot JVM.
Денормализация модели
class Cursor < String icon; Position pos; Cursor(String icon, int x, int y) < this.icon = icon; this.pos = new Position(x, y); >> class Position < int x; int y; Position(int x, int y) < this.x = x; this.y = y; >>
Казалось бы — избавились от композиции и все. Но нет. Объект класса Cursor2 потребляет приблизительно на 30% меньше памяти чем объект класса Cursor (по сути Cursor + Position). Такое вот не очевидное следствие декомпозиции. За счет ссылки и заголовка лишнего объекта. Возможно это кажется не важным и смешным, но только до тех пор, пока объектов у Вас мало, а когда счет идет на миллионы ситуация кардинально меняется. Это не призыв к созданию огромных классов по 100 полей. Ни в коем случаем. Это может пригодится исключительно в случае, когда Вы вплотную подошли к верхней границе Вашей оперативной памяти и в памяти у Вас много однотипных объектов.
Используем смещение в свою пользу
- Бывает возникает ситуации когда думаешь — «стоит ли добавить еще одно поле в класс или сэкономить и высчитать его позже на ходу?». Иногда глупо жертвовать процессорным временем ради экономии памяти, учитывая что никакой экономии может и не быть вовсе.
- Иногда можем добавить поле не тратя память, а в поле хранить дополнительные или промежуточные данные для вычислений или кеша (пример поле hash в классе String).
- Иногда нету никакого смысла использовать byte вместо int, так как за счет выравнивания разница все равно может нивелироваться.
Примитивы и оболочки
Еще раз повторюсь. Но если в Вашем классе поле не должно или не может принимать null значений смело используйте примитивы. Потому что очень уж часто встречается что-то вроде:
Помните, примитивы в среднем занимают в 4 раза меньше памяти. Замена одного поля Integer на int позволит сэкономить 16 байт памяти на объект. А замена одного Long на long — 20 байт. Также снижается нагрузка на сборщик мусора. Вообщем масса преимуществ. Единственная цена — отсутствие null значений. И то, в некоторых ситуациях, если память сильно уж нужна, можно использовать определенные значения в качестве null значений. Но это может повлечь доп. расходы на пересмотр логики приложения.
Boolean и boolean
Отдельно хотел бы выделить эти два типа. Все дело в том, что это самые загадочные типы в java. Так как их размер не определен спецификацией, размер логического типа полностью зависит от Вашей JVM. Что касается Oracle HotSpot JVM, то у всех у них под логический тип выделяется 4 байта, то есть столько же сколько и под int. За хранение 1 бита информации Вы платите 31 битом в случае boolean. Если говорить о массиве boolean, то большинство компиляторов проводит некую оптимизацию и в этом случае boolean будут занимать по байту на значение (ну и не забываем про BitSet).
Ну и напоследок — не используйте тип Boolean. Мне трудно придумать ситуацию, где он реально может потребоваться. Гораздо дешевле с точки зрения памяти и проще с точки зрения бизнес логики использовать примитив, который бы принимал 2 возможных значения, а не 3, как в случае в Boolean.
Сериализация и десериализация
Предположим у Вас есть сериализированая модель приложения и на диске она занимает 1 Гб. И у Вас стоит задача восстановить эту модель в памяти — попросту десериализовать. Вы должны быть готовы к тому, что в зависимости от структуры модели, в памяти она будет занимать от 2Гб до 5Гб. Да да, все опять из-за тех же заголовков, смещений и ссылок. Поэтому иногда может быть полезным содержать большие объемы данных в файлах ресурсов. Но это, конечно, очень сильно зависит от ситуации и это не всегда выход, а иногда и попросту невозможно.
Порядок имеет значение
Казалось бы — никакой разницы. Но на самом деле это не так… С точки зрения потребления памяти — разница колоссальна. В первом случае мы имеем 2 ссылки на массив из тысячи элементов. Во втором случае у нас есть тысяча ссылок на массивы c двумя элементами! С точки зрения памяти во втором случае количество потребляемой памяти больше на 998 размеров ссылок. А это около 7кб. Вот так на ровном месте можно потерять достаточно много памяти.
Сжатие ссылок
- Все объекты у которых есть ссылка, теперь занимают на 4 байта меньше на каждую ссылку.
- Сокращается заголовок каждого объекта на 4 байта.
- В некоторых ситуациях возможны уменьшенные выравнивания.
- Существенно уменьшается объем потребляемой памяти.
- Количество возможных объектов упирается в 2^32. Этот пункт сложно назвать минусом. Согласитесь, 4 млрд объектов очень и очень не мало. А еще учитывая, что минимальный размер объекта — 16 байт.
- Появляются доп. расходы на преобразование JVM ссылок в нативные и обратно. Сомнительно, что эти расходы способны хоть как-то реально повлиять на производительность, учитывая что это буквально 2 регистровые операции: сдвиг и суммирование. Детали можно найти тут
Заключение
Надеюсь мне удалось Вас убедить. Часть из этих приемов мне довелось повидать на реальных проектах. И помните, как говаривал Дональд Кнут, преждевременная оптимизация — это корень всех бед.
What is the size of a boolean variable in Java?
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
8 Answers 8
It depends on the virtual machine, but it’s easy to adapt the code from a similar question asking about bytes in Java:
class LotsOfBooleans < boolean a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af; boolean b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf; boolean c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf; boolean d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df; boolean e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef; >class LotsOfInts < int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af; int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf; int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf; int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df; int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef; >public class Test < private static final int SIZE = 1000000; public static void main(String[] args) throws Exception < LotsOfBooleans[] first = new LotsOfBooleans[SIZE]; LotsOfInts[] second = new LotsOfInts[SIZE]; System.gc(); long startMem = getMemory(); for (int i=0; i < SIZE; i++) < first[i] = new LotsOfBooleans(); >System.gc(); long endMem = getMemory(); System.out.println ("Size for LotsOfBooleans: " + (endMem-startMem)); System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE))); System.gc(); startMem = getMemory(); for (int i=0; i < SIZE; i++) < second[i] = new LotsOfInts(); >System.gc(); endMem = getMemory(); System.out.println ("Size for LotsOfInts: " + (endMem-startMem)); System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE))); // Make sure nothing gets collected long total = 0; for (int i=0; i < SIZE; i++) < total += (first[i].a0 ? 1 : 0) + second[i].a0; >System.out.println(total); > private static long getMemory() < Runtime runtime = Runtime.getRuntime(); return runtime.totalMemory() - runtime.freeMemory(); >>
To reiterate, this is VM-dependent, but on my Windows laptop running Sun’s JDK build 1.6.0_11 I got the following results:
Size for LotsOfBooleans: 87978576 Average size: 87.978576 Size for LotsOfInts: 328000000 Average size: 328.0
That suggests that booleans can basically be packed into a byte each by Sun’s JVM.