Java 가상 머신 사양 부울 제한적으로 지원이 있음을 말한다 원시 유형.
부울 값에 대한 조작 전용 Java 가상 머신 명령은 없습니다. 대신 부울 값에 대해 작동하는 Java 프로그래밍 언어의 표현식은 Java 가상 머신 int 데이터 유형의 값을 사용하도록 컴파일됩니다.
위의 내용은 부울에서 작동 할 때 int 데이터 유형이 사용되지만 32 비트 메모리 구성이라는 것을 암시합니다 (잘못 해석했을 수 있음). 부울은 1 비트의 정보 만 나타냅니다.
- 바이트 또는 짧은 유형이 int 대신 부울에 대한 프록시로 사용되지 않는 이유는 무엇입니까?
- 주어진 JVM에 대해 부울 유형을 저장하는 데 정확히 얼마나 많은 메모리가 사용되는지 알아내는 가장 안정적인 방법은 무엇입니까?
답변
짧은 대답 : 예, 부울 값은 32 비트 엔터티로 조작되지만 부울 배열은 요소 당 1 바이트를 사용합니다.
더 긴 답변 : JVM은 로컬 변수, 메소드 인수 및 표현식 값을 보유하는 데 사용되는 32 비트 스택 셀을 사용합니다. 1 셀보다 작은 프리미티브는 패딩되고 32 비트 (long 및 double)보다 큰 프리미티브는 2 셀을 사용합니다. 이 기술은 opcode의 수를 최소화하지만 몇 가지 특이한 부작용 (예 : 바이트 마스킹 필요)이 있습니다.
배열에 저장된 프리미티브는 32 비트 미만을 사용할 수 있으며 배열에서 프리미티브 값을로드하고 저장하는 데 서로 다른 opcode가 있습니다. 부울 및 바이트 값은 모두 baload
및 bastore
opcode를 사용하며 이는 부울 배열이 요소 당 1 바이트를 사용함 을 의미합니다.
메모리 내 개체 레이아웃에 관한 한, 이것은 “비공개 구현” 규칙에 따라 다룹니다 . 1 비트, 1 바이트 또는 다른 포스터에서 언급했듯이 64 비트 더블 워드 경계에 정렬 될 수 있습니다. 대부분의 경우 기본 하드웨어의 기본 워드 크기 (32 비트 또는 64 비트)를 사용합니다.
부울이 사용하는 공간의 양을 최소화하는 한 : 대부분의 응용 프로그램에서는 실제로 문제가되지 않습니다. 스택 프레임 (지역 변수 및 메서드 인수 포함)은 그다지 크지 않으며 큰 체계에서 객체의 이산 부울도 그다지 크지 않습니다. 부울이 많은 객체가 많은 경우 getter 및 setter를 통해 관리되는 비트 필드를 사용할 수 있습니다. 그러나 메모리의 패널티보다 더 큰 CPU 시간의 패널티를 지불하게됩니다.
답변
상속 계층의 어딘가에 단일 부울은 최대 8 바이트를 사용할 수 있습니다! 이것은 패딩 때문입니다. 자세한 내용은 Java 개체에서 사용하는 메모리 양을 참조하십시오 . :
부울이 소비하는 양에 대한 질문으로 돌아가서, 예, 적어도 1 바이트를 소비하지만 정렬 규칙으로 인해 훨씬 더 많이 소비 할 수 있습니다. IMHO boolean []이 항목 당 1 바이트가 아닌 1 비트를 소비하고 정렬 및 배열의 크기 필드로 인해 약간의 오버 헤드가 발생한다는 사실을 아는 것이 더 흥미 롭습니다. 큰 비트 필드가 유용한 그래프 알고리즘이 있으며, boolean []을 사용하는 경우 실제로 필요한 것보다 거의 정확히 8 배 더 많은 메모리가 필요합니다 (1 바이트 대 1 비트).
답변
5th Edition of Java in a Nutshell (O’Reilly)에서는 부울 기본 유형이 1 바이트라고 말합니다. 힙 검사 결과에 따라 잘못된 것일 수 있습니다. 대부분의 JVM이 변수에 1 바이트 미만을 할당하는 데 문제가 있는지 궁금합니다.
답변
부울 매핑은 32 비트 CPU를 염두에두고 수행되었습니다. int 값은 32 비트이므로 한 번의 작업으로 처리 할 수 있습니다.
다음은 Peter Norvig의 Java IAQ : Infrequently Answered Questions 에서 크기를 측정하기 위한 솔루션입니다 (일부 부정확 함).
static Runtime runtime = Runtime.getRuntime();
...
long start, end;
Object obj;
runtime.gc();
start = runtime.freememory();
obj = new Object(); // Or whatever you want to look at
end = runtime.freememory();
System.out.println("That took " + (start-end) + " bytes.");
답변
CPU는 특정 데이터 유형 길이에서 작동합니다. 32 비트 CPU의 경우 32 비트 길이이므로 Java에서 ‘int’라고 부릅니다. CPU가 처리하기 전에 아래 또는 위의 모든 항목을이 길이로 채우거나 분할해야합니다. 시간이 많이 걸리지는 않지만 기본 작업에 1 개 대신 2 개의 CPU주기가 필요한 경우 비용 / 시간이 두 배가됩니다.
이 사양은 32 비트 CPU 전용이므로 기본 데이터 유형으로 부울을 처리 할 수 있습니다.
여기에는 속도 또는 메모리 중 하나만있을 수 있습니다. SUN은 속도를 결정했습니다.
답변
부울은 정보의 한 비트를 나타내지 만 “크기”는 정확하게 정의 된 것이 아닙니다. Sun Java 자습서는 말합니다. 부울 리터럴에는 true와 false의 두 가지 가능한 값만 있습니다. 자세한 내용은 Java 데이터 유형 을 참조하십시오.
답변
다음과 같이 하나의 .java 파일을 만드는 것은 어떨까요?
Empty.java
class Empty{
}
다음과 같은 클래스 :
NotEmpty.java
class NotEmpty{
boolean b;
}
둘 다 컴파일하고 .class 파일을 16 진 편집기와 비교하십시오.