# 4장. 자바가 확장한 객체 지향

#### <mark style="color:blue;">왜 프로그램이 실행될 때 바로 클래스들의 정보를 T 메모리의 static 영역에 로딩하지 않고 해당 클래스가 처음 호출될 때 로딩할까?</mark>

클래스 정보는 해당 클래스가 코드에서 맨 처음 사용될 때 T 메모리의 스태틱 영역에 로딩되며, 이때 단 한번 해당 클래스의 `static` 블록이 실행된다.

클래스가 호출되는 경우

* 클래스의 정적 속성을 사용할 때
* 클래스의 정적 메서드를 사용할 때
* 클래스의 인스턴스를 최초로 만들 때

질문으로 다시 돌아와, 왜 클래스를 호출할 때 로딩할까? 그 이유는 JVM 메모리 구조의 `static` 영역도 메모리이기 때문이다.

메모리는 디스크에 비해 용량이 작기 때문에 최대한 늦게 사용을 시작하고 최대한 빨리 반환하는 것이 정석이다. 물론, 자바에서 `static` 영역에 올라간 데이터는 프로그램이 종료되기 전 까지 반환할 수 없지만, 그럼에도 최대한 늦게 로딩함으로써 메모리 사용을 늦추기 위해서이다.

#### <mark style="color:blue;">멤버 변수만 다른 동일한 타입의 객체를 100개 이상 만들고, 같은 메서드를 실행하면 heap 영역에 100개의 객체 프레임이 생길까?</mark>

```java
public class Example {  
    void test() {  
        System.out.println("Test");  
    }  
}  
  
  
class ExampleMain {  
    public static void main(String[] args) {  
        Example example = new Example();  
        example.test();  
    }  
}
```

만약 위와 같은 코드가 있다면 메모리구조는 아래와 같이 형성된다.

<figure><img src="https://2866575076-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVJhVCjGzSpinr6v1FHUo%2Fuploads%2F4bzjvbDLKvgsEFiwU7dc%2Fimage.png?alt=media&#x26;token=a8abed66-952f-4df7-8b93-5475e49ab281" alt=""><figcaption></figcaption></figure>

여기서 집중해서 봐야 할 관점은 `Example` 객체가 생성한 `example` 이 하나가 아닌, `Example[100]` 과 같이 요소가 100개인 배열이라면 힙 영역에 생기는 객체 프레임은 100개가 되고, `test()` 메서드도 각 객체에 따라 프레임 내부에 만들어져야한다.

객체 멤버 메서드는 각 객체별로 달라지는 것이 아니며, 새롭게 생성되는 객체 멤버 속성 값만 다를뿐이다.

이렇게 똑같은 객체 멤버 메서드인 `test()` 메서드를 힙 영역에 100개나 만드는 것은 심각한 메모리 낭비이다. 그래서, JVM 은 지능적으로 객체 멤버 메서드 `test()` 를 위 그림 처럼 스태틱 영역에 단 하나만 보유한다.

그리고 직접 코드상 눈에 보이지 않지만 `test()` 메서드를 호출할 때 객체 자신을 나타내는 `this` 객체 참조 변수를 인자로 넘긴다.

<figure><img src="https://2866575076-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVJhVCjGzSpinr6v1FHUo%2Fuploads%2Fzb5LiSzVy3JOr8rIgVmF%2Fimage.png?alt=media&#x26;token=3d745898-5a88-4b27-b9c8-18727f852911" alt=""><figcaption></figcaption></figure>

이로써 비효율적으로 메모리를 낭비하지않고 JVM 이 컴파일 당시 바이트 코드를 조작하여 최적화를 하면서 메모리 구조를 효율적으로 사용하게 된다.
