Каков размер пустого класса в C++, Java?
Каков размер пустого класса в C++ и Java? Почему это не ноль?sizeof();
возвращает 1 в случае C++.
8 ответов
Короткий ответ:
Стандарт прямо говорит, что класс не может иметь нулевой размер.
Длинный ответ:
Поскольку каждый объект должен иметь уникальный адрес (также определенный в стандарте), у вас не может быть объектов нулевого размера.
Представьте себе массив объектов нулевого размера. Поскольку они имеют нулевой размер, они все выстраиваются в одну и ту же адресную папку. Поэтому проще сказать, что объекты не могут иметь нулевой размер.
Даже если объект имеет ненулевой размер, если он фактически занимает нулевое пространство, ему не нужно увеличивать размер производного класса:
Пример:
#include <iostream>
class A {};
class B {};
class C: public A, B {};
int main()
{
std::cout << sizeof(A) << "\n";
std::cout << sizeof(B) << "\n";
std::cout << sizeof(C) << "\n"; // Result is not 3 as intuitively expected.
}
g++ ty.cpp
./a.out
1
1
1
В случае Java:
- Нет простого способа узнать, сколько памяти занимает объект в Java; то есть нет
sizeof
оператор. - Размер объекта (пустой или непустой) зависит от платформы.
Размер экземпляра "пустого класса" (т.е. java.lang.Object
) не равен нулю, поскольку экземпляр имеет неявное состояние, связанное с ним. Например, требуется состояние:
- так что объект может функционировать как примитивный замок,
- представлять свой хэш-код личности,
- чтобы указать, был ли объект завершен,
- ссылаться на класс времени выполнения объекта,
- держать биты метки GC объекта,
- и так далее.
Текущие JVM Hotspot используют хитрые трюки для представления состояния в заголовке объекта, который занимает два 32-битных слова. (Это расширяется в некоторых обстоятельствах; например, когда примитивная блокировка фактически используется, или после identityHashCode()
называется.)
Поскольку каждый объект C++ должен иметь отдельный адрес, невозможно иметь класс с нулевым размером (кроме некоторых особых случаев, связанных с базовыми классами). В C++ есть больше информации : каков размер объекта пустого класса?,
Поскольку объект должен иметь адрес в памяти и иметь адрес в памяти, он должен занимать "некоторую" память. Так, обычно в C++ это наименьшее возможное количество, то есть 1 символ (но это может зависеть от компилятора). В Java я не был бы так уверен... у него могли бы быть некоторые данные по умолчанию (больше чем просто заполнитель как в C++), но было бы удивительно, если бы это было намного больше, чем в C++.
C++ требует, чтобы его обычное создание имело размер как минимум 1 (может быть больше, хотя я не знаю компилятора, который это делает). Однако он допускает "пустую оптимизацию базового класса", поэтому, хотя класс имеет минимальный размер 1, когда он используется в качестве базового класса, ему не нужно ничего добавлять к размеру производного класса.
Я думаю, что Java, вероятно, делает то же самое. Причина, по которой C++ требует размер как минимум 1, заключается в том, что он требует, чтобы каждый объект был уникальным. Рассмотрим, например, массив объектов с нулевым размером. Все объекты будут находиться по одному адресу, поэтому у вас будет только один объект. Разрешение нуля звучит как рецепт проблем...
Он определяется стандартом C++ как "ненулевое значение", потому что выделенный объект должен иметь ненулевой размер, чтобы иметь отдельный адрес. Класс, который наследуется от пустого класса, однако, не обязан увеличиваться в размере, за исключением обычного увеличения виртуальной таблицы, если задействованы виртуальные функции.
Как уже отмечали другие, объекты C++ не могут иметь нулевой размер. Классы могут иметь нулевой размер только тогда, когда они действуют как подкласс другого класса. Посмотрите на ответ @Martin York для описания с примерами - а также посмотрите и проголосуйте за другие ответы, которые являются правильными в этом отношении.
В Java в виртуальной машине горячей точки накладные расходы памяти составляют 2 машинных слова (обычно 4 байта в 32 арках на слово) на объект для хранения информации бухгалтерского учета вместе с информацией о типе среды выполнения. Для массивов требуется третье слово для хранения размера. Другие реализации могут занимать другой объем памяти (классическая Java VM, по той же ссылке, занимала 3 слова на объект)
Я не знаю, есть ли оператор sizeof() в Java. Что вы можете сделать, это создать экземпляр пустого класса (иметь его сериализуемость), отправить его через PipedOutputStream и прочитать его как байтовый массив - byteArray.length даст вам размер.
В качестве альтернативы, запишите экземпляр в файл с помощью DataOutputStream, закройте файл, откройте его, и file.length() даст вам размер объекта. Надеюсь, это поможет, - MS