Nice programing

Java-널 변수에 메모리 공간이 필요합니까?

nicepro 2020. 11. 28. 12:26
반응형

Java-널 변수에 메모리 공간이 필요합니까?


class CheckStore {
    private String displayText;
    private boolean state;
    private String meaningfulText;
    private URL url;

    public CheckStore(String text, boolean state) {
        this.displayText = text;
        this.state = state;
    }
    :
    :
}

생성자에서 두 개의 변수 ( displayTextstate) 만 초기화 하므로 나머지 두 변수 ( meaningfulTexturl값이 있음 null)는 null을 저장하기 위해 메모리 공간이 필요 합니다.

Q1. 공간이 필요하다고 생각합니다. 그렇다면 null값이 메모리에서 차지하는 메모리 양 (예 : int4 바이트).

Q2. 문자열이 메모리에서 차지하는 공간입니다. 나는 그것이 문자열의 길이에 달려 있다고 생각합니다. 그러면 문자열이 얼마나 많은 길이를 차지할까요?


Java에서는 null참조 (기본적으로 제한된 포인터)가 가질 수있는 값입니다. 참조가 아무것도 언급하지 않음을 의미합니다. 이 경우에도 여전히 참조 용 공간을 사용합니다. 32 비트 시스템에서는 4 바이트, 64 비트 시스템에서는 8 바이트입니다. 그러나 실제로 참조를 가리키는 해당 클래스의 인스턴스를 할당 할 때까지 참조가 가리키는 클래스에 대한 공간을 소비하지 않습니다.

편집 : 문자열에 관한 한 String, Java의 a 는 각 문자에 대해 16 비트 (2 바이트)와 소량의 부기 오버 헤드를 사용합니다. 이는 아마도 문서화되지 않고 구현에 따라 다릅니다.


추가하고 싶습니다 :

  1. 참조 유형의 변수는 null 값으로 초기화됩니다.
  2. null은 개체가 아닙니다. (null instanceof Object)가 false와 같기 때문에
  3. JVM에는 하나의 널값 만 있습니다. 얼마나 많은 변수가 null을 참조하든 상관 없습니다.

    객체 s = (문자열) null;

    Object i = (Integer) null;

    System.out.println (s == i); // true


jol사용 하여 해당 클래스의 레이아웃을 가져올 수 있습니다 . (그러나 조심하십시오. 그 뒤에있는 메커니즘에 대한 더 깊은 이해가 필요할 수 있습니다. 결과를 맹목적으로 신뢰하지 말고 현재 사용되는 VM에 대한 추정치 일뿐입니다 (제 경우에는 1.7.0_76 x64 승리 :).

CLI 버전을 사용합니다. 적절한 방법은 프로젝트에 라이브러리를 포함하는 것이지만 어쨌든 다음과 같이 작동하는 것 같습니다.

test>java -cp target\classes;jol-cli-0.3.1-full.jar org.openjdk.jol.Main internals test.CheckStore
Running 64-bit HotSpot VM.
Using compressed oop with 0-bit shift.
Using compressed klass with 0-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

VM fails to invoke the default constructor, falling back to class-only introspection.

test.CheckStore object internals:
 OFFSET  SIZE    TYPE DESCRIPTION                    VALUE
      0    12         (object header)                N/A
     12     1 boolean CheckStore.state               N/A
     13     3         (alignment/padding gap)        N/A
     16     4  String CheckStore.displayText         N/A
     20     4  String CheckStore.meaningfulText      N/A
     24     4     URL CheckStore.url                 N/A
     28     4         (loss due to the next object alignment)
Instance size: 32 bytes (estimated, the sample instance is not available)
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total

자동 압축 된 죄송합니다.

test>java -XX:-UseCompressedOops -cp target\classes;jol-cli-0.3.1-full.jar org.openjdk.jol.Main internals test.CheckStore
Running 64-bit HotSpot VM.
Objects are 8 bytes aligned.
Field sizes by type: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

VM fails to invoke the default constructor, falling back to class-only  introspection.

test.CheckStore object internals:
 OFFSET  SIZE    TYPE DESCRIPTION                    VALUE
      0    16         (object header)                N/A
     16     1 boolean CheckStore.state               N/A
     17     7         (alignment/padding gap)        N/A
     24     8  String CheckStore.displayText         N/A
     32     8  String CheckStore.meaningfulText      N/A
     40     8     URL CheckStore.url                 N/A
Instance size: 48 bytes (estimated, the sample instance is not available)
Space losses: 7 bytes internal + 0 bytes external = 7 bytes total

Those are only the layouts for the object itself if your fields are null, then it will not point to more objects, otherwise you have to look at the target types (URL and String) as well. (And if you have multiple instances of all of them it depends if you use the same multiple times or different ones). An null field cannot be skipped in memory, as it would require the instance to be resized when it is assigned. So the fields are all pre-constructed, they just do not reference allocated objects somewhere else on the heap.

NB: you get some more details if you implement a default constructor, but the sizing in this specific case would be the same. In case you wonder where the sequence and padding of fields is coming from, you can check this article - (basically it aligns objects on 8 bytes, sorts fields by size, groups same type together, references last. Fields from super types are first, 4 byte aligned.)


Null means 0. There is usually one place null defined in memory. Whenever one points to it using a programming language. Everything points to same place. It means only one 4 byte memory is consumed for NULL. Then whatever points to it does not consume any more memory. Definition of NULL is language specific but defining it void *ptr=0; is common in C and C++. JAVA must have defined it similarly. It is not possible to point to nothing ofc. You have to point to something. But we define a common nothing and everything points to it consume only that space.

참고URL : https://stackoverflow.com/questions/2430655/java-does-null-variable-require-space-in-memory

반응형