Есть ли какой-нибудь метод sizeof в Java?

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

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

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

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


@Davor указывает, что sizeof(someInt) будет более читаемым, чем 4 . Я не уверен, что согласен … потому что я думаю, что каждый программист Java должен знать, что int всегда 32 бита (4 байта). (И кроме того, редко бывает необходимо использовать размер типа в Java-коде …)

Однако, если вы принимаете этот аргумент удобочитаемости, тогда средство находится в ваших armх. Просто определите class, подобный этому …

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

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

 import static PrimitiveSizes.*; 

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

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

Ключевое слово в вышесказанном – это они . (Неважно, что вы или я об этом думаем … если у вас нет какого-то влияния в процессе принятия решений.)

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


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

Из статьи в JavaWorld

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

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

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

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

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

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

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

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

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

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

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

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

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

 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; } 

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

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

Я решил создать перечисление без соблюдения стандартных соглашений 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; } 

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

EhCache предоставляет class SizeOf, который будет пытаться использовать агент Instrumentation и будет возвращаться к другому подходу, если агент не загружен или не может быть загружен ( подробности здесь ).

Также см. Агент от Хайнца Кабуца .

На SourceForge.net есть class / jar, который использует инструменты Java для расчета размера любого объекта. Вот ссылка на описание: java.sizeOf

Попробуйте java.lang.Instrumentation.getObjectSize (Object) . Но, пожалуйста, имейте в виду, что

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

Существует современный способ сделать это для примитивов. Используйте 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 
  • Как преобразовать данные Firebase в объект Java ...?
  • Какой метод в Java используется для уничтожения ваших объектов
  • TCP \ IP-клиент - EHOSTUNREACH (нет пути к хосту)
  • Android - обновить контакт
  • Android Webview: невозможно вызвать функцию definVisibility () - никогда не видел подключения для pid
  • как получить максимальное значение из списка / ArrayList
  • Есть ли способ получить количество меток чисел, используемых в файле jar
  • Не удалось выполнить dex: превышение верхнего предела GC в Eclipse
  • Передача функции в качестве параметра в java
  • Как я могу обрезать bitmap для ImageView?
  • Не удается разрешить метод getMap ()
  • Давайте будем гением компьютера.