Java에서 부울 변수의 크기는 얼마입니까?


89

누구든지 Java에서 부울 의 비트 크기를 알 수 있습니까 ?


1
여기에 동일한 질문이 있습니다. stackoverflow.com/questions/1907318/…
dma_k

답변:


41

가상 머신에 따라 다릅니다.


9
일부 문서를 가리켜 보시겠습니까? 부울의 크기가 기계에 따라 다르다는 것을 믿기가 어렵습니다. 이는 부울을 포함하는 클래스의 이진 표현이 다른 VM에서 다른 크기 (및 메모리 레이아웃)를 가지며 VM이 호환되지 않음을 의미합니다.
David Rodríguez-dribeas

14
나는 질문이 클래스 파일에 인코딩 된 부울 변수의 크기가 아니라 메모리의 부울 변수 크기를 참조한다는 것을 암시한다고 생각합니다. 메모리의 크기는 Sun 설명서에 따라 VM에 따라 다릅니다. 클래스 파일의 크기는 일정합니다.
William Brendel

3
@ DavidRodríguez-dribeas-Java 1.1 당시 Sun JVM은 인스턴스 또는 자동 변수로 저장 될 때 부울에 4 바이트를 사용했습니다. 이것은 바이트 코드 인터프리터 (부울이 스택에서 4 바이트를 차지하는 것으로 간주)의 구현을 단순화했으며 저항이 가장 적은 경로였습니다. iSeries "Classic"JVM을 구현했을 때 인스턴스 vars를 1 바이트로 만드는 방법을 찾았습니다. 이는 일부 객체의 압축성을 크게 향상 시켰기 때문입니다 (성능에 놀라운 영향을 미침). 분명히 아래 게시물을 기반으로 Sun / Oracle 개발자는 이후 버전에서 이와 동일한 작업을 수행하는 방법을 알아 냈습니다.
Hot Licks 2013

그러나, 맞아 후반 2017로 JavaDoc을은 : 대답 boolean: The boolean data type... This data type represents one bit of information, but its "size" isn't something that's precisely defined:)하지만 점은 몇 가지 링크와 더 나은 정보를 사용할 수, 유효 -
JimLohse

185

가상 머신에 따라 다르지만 Java의 바이트에 대해 묻는 유사한 질문 의 코드를 쉽게 수정할 수 있습니다 .

class LotsOfBooleans
{
    boolean a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    boolean b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    boolean c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    boolean d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    boolean e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
}

class LotsOfInts
{
    int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
    int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
    int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
    int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
    int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
}


public class Test
{
    private static final int SIZE = 1000000;

    public static void main(String[] args) throws Exception
    {        
        LotsOfBooleans[] first = new LotsOfBooleans[SIZE];
        LotsOfInts[] second = new LotsOfInts[SIZE];

        System.gc();
        long startMem = getMemory();

        for (int i=0; i < SIZE; i++)
        {
            first[i] = new LotsOfBooleans();
        }

        System.gc();
        long endMem = getMemory();

        System.out.println ("Size for LotsOfBooleans: " + (endMem-startMem));
        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));

        System.gc();
        startMem = getMemory();
        for (int i=0; i < SIZE; i++)
        {
            second[i] = new LotsOfInts();
        }
        System.gc();
        endMem = getMemory();

        System.out.println ("Size for LotsOfInts: " + (endMem-startMem));
        System.out.println ("Average size: " + ((endMem-startMem) / ((double)SIZE)));

        // Make sure nothing gets collected
        long total = 0;
        for (int i=0; i < SIZE; i++)
        {
            total += (first[i].a0 ? 1 : 0) + second[i].a0;
        }
        System.out.println(total);
    }

    private static long getMemory()
    {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
}

다시 말하면 이것은 VM에 따라 다르지만 Sun의 JDK 빌드 1.6.0_11을 실행하는 Windows 랩톱에서 다음과 같은 결과를 얻었습니다.

Size for LotsOfBooleans: 87978576
Average size: 87.978576
Size for LotsOfInts: 328000000
Average size: 328.0

이는 부울이 기본적으로 Sun의 JVM에 의해 각각 바이트로 압축 될 수 있음을 의미합니다.


21
@skeet - 정말 경례있어 네 대답은 굉장
전사

2
@warrior : "바이트"에 대한 코드를 이미 받았기 때문에 "부울"로 변경하는 것은 매우 간단합니다. :)
Jon Skeet

3
System.gc ()는 메모리 정리를 보장하지 않습니다. JVM에 가비지 컬렉션을 실행하도록 명령 할 뿐이지 만 수집기가 실제로 무언가를 청소했다는 의미는 아닙니다. 수집기는 사용하지 않는 개체를 정리합니다. 프로그램이 더 이상 참조를 보유하지 않으면 객체는 사용되지 않습니다. 따라서 테스트에서 gc ()를 실행하기 전에 LotsOfBooleans를 null로 설정하여 참조를 명시 적으로 삭제합니다. 또는 부울로 main을 한 번 실행하고 int로 한 번 실행 한 다음 숫자를 비교하십시오.
Randa Sbeity 2014 년

2
@RandaSbeity 또는 더 나은 방법 : 두 참조를 모두 보존하고 메모리 차이를 계산하십시오. 정확히 여기서 일어나는 일입니다.
biziclop

1
Jon Skeet이 대답 할 수없는 질문이 있습니까?
Andreas Hartmann

31

Java에서 부울 값으로 표시되는 실제 정보는 1 비트입니다. 1은 true, 0은 false입니다. 그러나 메모리에있는 부울 변수의 실제 크기는 Java 사양에 의해 정확하게 정의되지 않습니다. Java의 기본 데이터 유형을 참조하십시오 .

부울 데이터 유형에는 true 및 false의 두 가지 가능한 값만 있습니다. 참 / 거짓 조건을 추적하는 간단한 플래그에이 데이터 유형을 사용하십시오. 이 데이터 유형은 정보의 1 비트를 나타내지 만 "크기"는 정확하게 정의 된 것이 아닙니다.


21

참고로 ...

Boolean 객체 배열을 사용할 생각이라면 사용하지 마십시오. 대신 BitSet을 사용하십시오-성능 최적화가 가능합니다 (그리고 다음 설정 / 설정 해제 비트를 얻을 수있는 몇 가지 멋진 추가 방법).


이것은 항상 사실이 아니다 stackoverflow.com/questions/605226/...
Przemek

그 대답은 boolean []을 사용하는 중요한 이유가 있음을 시사하지만 주석에서 알 수 있듯이 백업 할 것이 많지 않습니다. 나는 자바에서 많은 프로그램을하지 않습니다 (그리고 하나 증거를 제공하지 않았다) : 그런 말로 미루어 보아
매튜 Schinckel

6

Java는 boolean데이터 유형에 대해 1 바이트를 예약 하지만 1 비트 만 사용 한다고 읽었습니다 . 그러나 문서에 따르면 "크기"는 정확하게 정의 된 것이 아닙니다 . 여길 봐.


그것은 '문서'가 아니라 튜토리얼입니다. 설명서는 JLS, JVM 사양 및 Javadoc입니다.
Marquis of Lorne

2

boolean값으로 컴파일 intJVM의 데이터 유형. 를 참조하십시오 여기 .


2
그것이 반드시 메모리에 저장되는 방법은 아니며 질문을하는 사람이 알고 싶어했던 것입니다. 이 문서는 구현에 따라 다르기 때문에 메모리에서 부울 변수의 표현이 아닌 클래스 파일 형식 (컴파일 된 바이트 코드)을 설명합니다.
William Brendel

2

Java의 부울 크기는 가상 머신에 따라 다릅니다. 그러나 모든 Java 객체는 8 바이트 단위로 정렬됩니다. 부울에는 총 9 바이트의 정보에 대해 8 바이트의 헤더와 1 바이트의 페이로드가 있습니다. JVM은 다음 8의 배수로 반올림하여 java.lang.Boolean의 한 인스턴스가 16 바이트의 메모리를 차지합니다.


HotSpot JVM 1.7.0_51에서 헤더는 부울에 대해 12 바이트 + 1 + 세분성을 위해 3을 갖습니다.
Eugene

14
부울과 부울을 혼동하지 마십시오.
andresp

1
바이트 또는 비트? A에 대한 16 바이트 Booleana의 크기의 수 고원 이러한 폐기물 ... long(A)보다 조 배 더 많은 정보를 전달할 수Boolean
DICI

0

정의되지 않았습니다. Jon Skeet이 제안한 것과 같은 작업을 수행하면 주어진 플랫폼에 대한 근사치를 얻을 수 있지만 특정 플랫폼에 대해 정확하게 아는 방법은 프로파일 러를 사용하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.