← Назад к вопросам

Где посмотреть сколько места занимают примитивы в Java?

1.2 Junior🔥 131 комментариев
#JVM и управление памятью#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Размер примитивных типов в Java

Стандартные размеры примитивов

В Java размеры примитивных типов определены в спецификации языка и занимают фиксированное место в памяти:

public class PrimitiveSizes {
    // byte - 1 байт (8 бит)
    byte b = 127;
    
    // short - 2 байта (16 бит)
    short s = 32767;
    
    // int - 4 байта (32 бита)
    int i = 2147483647;
    
    // long - 8 байт (64 бита)
    long l = 9223372036854775807L;
    
    // float - 4 байта (32 бита)
    float f = 3.14f;
    
    // double - 8 байт (64 бита)
    double d = 3.14159265359;
    
    // boolean - 1 байт (8 бит) в объекте, 1 бит в массиве
    boolean bool = true;
    
    // char - 2 байта (16 бит)
    char c = 'A';
}

Таблица размеров

ТипРазмерДиапазон
byte1 байт-128 до 127
short2 байта-32768 до 32767
int4 байта-2147483648 до 2147483647
long8 байтогромный диапазон
float4 байтаIEEE 754
double8 байтIEEE 754
boolean1 байтtrue/false
char2 байта0 до 65535

Проверка размеров через инструменты

1. Константы в языке

public class CheckSizes {
    public static void main(String[] args) {
        // Используем встроенные константы типов-обёрток
        System.out.println("Byte.SIZE: " + Byte.SIZE + " бит");
        System.out.println("Byte.BYTES: " + Byte.BYTES + " байт");
        
        System.out.println("Short.SIZE: " + Short.SIZE + " бит");
        System.out.println("Short.BYTES: " + Short.BYTES + " байт");
        
        System.out.println("Integer.SIZE: " + Integer.SIZE + " бит");
        System.out.println("Integer.BYTES: " + Integer.BYTES + " байт");
        
        System.out.println("Long.SIZE: " + Long.SIZE + " бит");
        System.out.println("Long.BYTES: " + Long.BYTES + " байт");
        
        System.out.println("Float.SIZE: " + Float.SIZE + " бит");
        System.out.println("Float.BYTES: " + Float.BYTES + " байт");
        
        System.out.println("Double.SIZE: " + Double.SIZE + " бит");
        System.out.println("Double.BYTES: " + Double.BYTES + " байт");
        
        System.out.println("Character.SIZE: " + Character.SIZE + " бит");
        System.out.println("Character.BYTES: " + Character.BYTES + " байт");
    }
}

// Вывод:
// Byte.SIZE: 8 бит
// Byte.BYTES: 1 байт
// Short.SIZE: 16 бит
// Short.BYTES: 2 байта
// Integer.SIZE: 32 бит
// Integer.BYTES: 4 байта
// Long.SIZE: 64 бит
// Long.BYTES: 8 байт
// Float.SIZE: 32 бит
// Float.BYTES: 4 байта
// Double.SIZE: 64 бит
// Double.BYTES: 8 байт
// Character.SIZE: 16 бит
// Character.BYTES: 2 байта

2. Java Memory Model документация

Размеры примитивов определены в JLS (Java Language Specification):

  • Section 4.2 (Primitive Types and Values)
  • Размеры фиксированы и одинаковы на всех платформах

3. Использование Unsafe для расчёта смещений

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public class MemoryLayout {
    public static void main(String[] args) throws Exception {
        // Получение Unsafe (не рекомендуется в production)
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);
        
        class MyClass {
            byte b;
            short s;
            int i;
            long l;
        }
        
        long b_offset = unsafe.objectFieldOffset(
            MyClass.class.getDeclaredField("b"));
        long s_offset = unsafe.objectFieldOffset(
            MyClass.class.getDeclaredField("s"));
        long i_offset = unsafe.objectFieldOffset(
            MyClass.class.getDeclaredField("i"));
        long l_offset = unsafe.objectFieldOffset(
            MyClass.class.getDeclaredField("l"));
        
        System.out.println("byte offset: " + b_offset);
        System.out.println("short offset: " + s_offset);
        System.out.println("int offset: " + i_offset);
        System.out.println("long offset: " + l_offset);
    }
}

4. JOL (Java Object Layout) - лучший инструмент

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;

public class SizeAnalysis {
    static class Data {
        byte b;
        short s;
        int i;
        long l;
    }
    
    public static void main(String[] args) {
        System.out.println(VM.current().details());
        System.out.println(ClassLayout.parseClass(Data.class).toPrintable());
    }
}

// Вывод:
// # Running 64-bit HotSpot VM.
// # Using compressed object pointers (oop size = 4 bytes).
// 
// org.example.SizeAnalysis$Data object internals:
//  OFFSET  SIZE   TYPE DESCRIPTION
//       0    12        (object header)
//      12     1   byte Data.b
//      13     1        (alignment/padding)
//      14     2  short Data.s
//      16     4    int Data.i
//      20     4        (padding)
//      24     8   long Data.l
// Instance size: 32 bytes

5. Спецификация Java

Оффициальные размеры из Java Language Specification:

byte:    1 байт (signed 8-bit two's complement integer)
short:   2 байта (signed 16-bit two's complement integer)
int:     4 байта (signed 32-bit two's complement integer)
long:    8 байт (signed 64-bit two's complement integer)
float:   4 байта (32-bit IEEE 754 single-precision floating point)
double:  8 байт (64-bit IEEE 754 double-precision floating point)
boolean: 1 байт (true/false, хотя битово может быть 1 бит)
char:    2 байта (16-bit unsigned Unicode character)

Важные замечания

Padding и Alignment

class Unoptimized {
    byte b;    // 1 байт, смещение 12
    long l;    // 8 байт, смещение 24 (padding 12-23)
    int i;     // 4 байта, смещение 32
}
// Итого: 40 байт (много padding)

class Optimized {
    long l;    // 8 байт, смещение 12
    int i;     // 4 байта, смещение 20
    byte b;    // 1 байт, смещение 24
}
// Итого: 32 байта (меньше padding)

Примитивы в объекте vs в массиве

// В объекте boolean занимает 1 байт
class WithBoolean {
    boolean flag;  // 1 байт
}

// В массиве boolean может занимать 1 бит
boolean[] flags = new boolean[8];  // примерно 1 байт на 8 значений

Вывод

Размеры примитивных типов в Java строго определены спецификацией и одинаковы на всех платформах. Для проверки можно использовать встроенные константы типов-обёрток (Integer.BYTES и т.д.) или JOL инструмент для детального анализа расположения в памяти.

Где посмотреть сколько места занимают примитивы в Java? | PrepBro