Есть ли подобный метод в Java? - PullRequest
71 голосов
/ 03 марта 2010

Есть ли в Java какой-либо встроенный метод для определения размера любого типа данных? Есть ли способ найти размер?

Ответы [ 13 ]

59 голосов
/ 03 марта 2010

Нет. В стандартной библиотеке классов Java SE такого метода нет.

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

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


Предыдущие комментаторы указывали, что sizeof(someType) будет более читабельным, чем 4. Если вы примете этот аргумент читабельности, значит, лекарство в ваших руках. Просто определите класс следующим образом ...

public class PrimitiveSizes {
    public static int sizeof(byte b) { return 1; } 
    public static int sizeof(short s) { return 2; }
    // etcetera
}

... и статически импортировать его ...

import static PrimitiveSizes.*;

Или определить несколько именованных констант; например,

public static final int SIZE_OF_INT = 4;

Или (Java 8 и более поздние версии) используйте константу Integer.BYTES и т. Д.


Почему разработчики Java не реализовали это в стандартных библиотеках? Я думаю, что:

  • они не думают, что в этом есть необходимость,
  • они не думают, что на него есть достаточный спрос, и
  • они не думают, что это стоит усилий.

Существует также проблема, связанная с тем, что следующим требованием будет метод sizeof(Object o), что чревато техническими трудностями.

Ключевое слово в вышесказанном - "они"!

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


1 - программисту может понадобиться знать, чтобы проектировать структуры данных с эффективным использованием пространства. Однако я не могу себе представить, почему эта информация понадобится в коде приложения во время выполнения посредством вызова метода.

14 голосов
/ 03 марта 2010

Из статьи в JavaWorld

Поверхностный ответ заключается в том, что Java не предоставляет ничего подобного sizeof () в C. Тем не мение, давайте рассмотрим, почему программисту на Java иногда хочется этого.

Программист на C самостоятельно управляет большинством распределений памяти в структуре данных, и sizeof () необходим для того, чтобы знать размеры блоков памяти для выделить. Кроме того, распределители памяти C, такие как malloc (), делают почти ничего, что касается инициализации объекта: программист должен установить все поля объекта, которые являются указателями на дальнейшие объекты. Но когда все сказано и закодировано, распределение памяти C / C ++ довольно эффективный.

Для сравнения, размещение объектов Java и их построение связаны между собой вместе (невозможно использовать выделенный, но неинициализированный экземпляр объекта). Если класс Java определяет поля, которые являются ссылками для дальнейших объектов, также обычно устанавливать их при строительстве время. Выделение объекта Java, следовательно, часто выделяет многочисленные экземпляры взаимосвязанных объектов: граф объектов. В сочетании с автоматическая сборка мусора, это слишком удобно и может сделать Вы чувствуете, что вам никогда не придется беспокоиться о распределении памяти Java подробности.

Конечно, это работает только для простых приложений Java. По сравнению с C / C ++, эквивалентные структуры данных Java, как правило, занимают больше объем памяти. В разработке программного обеспечения предприятия, приближаясь к Максимальная доступная виртуальная память на современных 32-разрядных виртуальных машинах Java является распространенной ограничение масштабируемости. Таким образом, Java-программист может извлечь выгоду из sizeof () или что-то подобное, чтобы следить за тем, структуры данных становятся слишком большими или содержат узкие места в памяти. К счастью, Java отражение позволяет вам написать такой инструмент довольно легко.

Прежде чем продолжить, я обойдусь без некоторых частых, но неправильных ответы на вопрос этой статьи. Ошибка: Sizeof () не требуется потому что размеры основных типов Java фиксированы

Да, Java int имеет 32 бита во всех JVM и на всех платформах, но это только требование спецификации языка для программируемая ширина этого типа данных. Такой инт по существу абстрактный тип данных и может быть поддержан, скажем, 64-разрядное слово физической памяти на 64-разрядной машине. То же самое касается Непримитивные типы: спецификация языка Java ничего не говорит о как поля класса должны быть выровнены в физической памяти или что массив булевых не может быть реализован как компактный битовый вектор внутри JVM. Ошибка: Вы можете измерить размер объекта, сериализовав его в поток байтов и глядя на результирующую длину потока

Причина, по которой это не работает, заключается в том, что макет сериализации только отдаленное отражение истинного расположения в памяти. Один простой способ увидеть это, посмотрев, как строки сериализуются: в памяти каждый символ не менее 2 байтов, но в сериализованном виде строки имеют формат UTF-8 и любой ASCII контент занимает вдвое меньше места

11 голосов
/ 04 ноября 2010

Библиотека * Native Access обычно используется для вызова собственных разделяемых библиотек из Java. В этой библиотеке существуют методы для определения размера объектов Java:

Метод getNativeSize(Class cls) и его перегрузки обеспечат размер для большинства классов.

В качестве альтернативы, если ваши классы наследуются от класса Structure JNA, будет доступен метод calculateSize(boolean force).

9 голосов
/ 30 апреля 2013

Вы можете делать битовые манипуляции, как показано ниже, чтобы получить размер примитивов:

public int sizeofInt() {
    int i = 1, j = 0;
    while (i != 0) {
        i = (i<<1); j++;
    }
    return j;
}

public int sizeofChar() {
    char i = 1, j = 0;
    while (i != 0) {
        i = (char) (i<<1); j++;
    }
    return j;
}
8 голосов
/ 04 января 2016

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

например. для long это может быть Long.SIZE / Byte.SIZE от Java 1.5 (как уже упоминалось zeodtr ) или Long.BYTES от Java 8

3 голосов
/ 10 апреля 2015

Вы можете использовать Integer.SIZE / 8, Double.SIZE / 8 и т. Д. Для примитивных типов из Java 1.5.

2 голосов
/ 07 августа 2018

Существует современный способ сделать это для примитивов.Используйте BYTES типов.

System.out.println("byte " + Byte.BYTES);
System.out.println("char " + Character.BYTES);
System.out.println("int " + Integer.BYTES);
System.out.println("long " + Long.BYTES);
System.out.println("short " + Short.BYTES);
System.out.println("double " + Double.BYTES);
System.out.println("float " + Float.BYTES);

В результате,

byte 1
char 2
int 4
long 8
short 2
double 8
float 4
1 голос
/ 30 октября 2016

Я решил создать enum без соблюдения стандартных соглашений Java. Возможно, вам это нравится.

public enum sizeof {
    ;
    public static final int FLOAT = Float.SIZE / 8;
    public static final int INTEGER = Integer.SIZE / 8;
    public static final int DOUBLE = Double.SIZE / 8;
}
1 голос
/ 04 ноября 2010

В классе Instrumentation есть метод getObjectSize (), однако вам не нужно использовать его во время выполнения. Самый простой способ проверить использование памяти - использовать профилировщик, который предназначен для отслеживания использования памяти.

0 голосов
/ 19 апреля 2018

Попробуйте java.lang.Instrumentation.getObjectSize (Object) . Но учтите, что

Возвращает зависящее от реализации приблизительное количество памяти, используемой указанным объектом. Результат может включать некоторые или все накладные расходы объекта и, таким образом, полезен для сравнения внутри реализации, но не между реализациями. Оценка может измениться во время одного вызова JVM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...