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.