모든 데이터 타입은 값 타입(value type) or 참조 타입(reference type) 을 가진다.
Java 언어의 데이터 타입

기본 타입 : 각각의 고유의 메모리를 소유한다.
기본 타입 특징

참조 타입 : 객체의 주소를 참조하는 타입이다.
JVM에서 heap 메모리에 저장되는 object는 다음과 같은 특성을 가집니다.
Java 에서 참조타입은 메모리를 어떻게 할당하는지 알아보고 찾은 정보.
**완벽하게 이해가 되지는 않는다..
- housekeeping 정보로 구성된 12 bytes의 object header 공간이 있습니다.
- Class Object (32 bits): 클래스 정보에 대한 포인터
- Flags (32 bits): 객체의 상태를 설명하는 플래그 모음 (hash-code가 있는지, array인지 등)
- Lock (32 bits): 동기화 정보, 동기화 잠금 여부
- primitive fields는 각자 정해진 크기만큼 차지한다.
- reference fields는 4 bytes를 차지한다.
- array 배열은 16 bytes가 필요합니다. object 공간 12 bytes + array length 공간 4 bytes
- object 크기는 항상 8의 배수만큼의 byte 공간을 차지합니다. '8-byte alignment', 'object alignment' 라고 합니다. 8의 배수만큼의 byte 공간을 맞춰주기 위해 padding 공간을 붙여줍니다.
기본타입과 참조타입의 차이는 저장되는 값이 무엇인가 이다.
기본 타입으로 선언된 변수는 실제 값을 변수에 저장하지만,
참조 타입은 선언된 변수는 메모리에 주소를 값으로 갖게 된다.

Java 프로그램은 JVM(Java Virtual Machine)이 실행된다. JVM은 운영체제에서 할당받은 메모리영역을 메소드 영역, 스레드 영역, 힙영역과 같이 세부 영역으로 구분해서 사용한다.
메소드 영역
메소드 영역은 JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역이다.
힙영역
힙 영역에서 생성된 객체와 배열은 JVM 스택 영역의 변수나, 다른 객체의 필드에서 참조한다. heap 영역에 객체를 참조하는 변수나 field가 존재하지 않으면 Garbage Collector에 의해 자동제거된다.
JVM Stack Area
JVM 스택 영역은 각 스레드마다 한개씩 존재하고, 스레드가 시작될 때 할당된다. JVM 스택은 메소드를 호출할 때마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 동작을 수행한다.
프레임 내부에는 로컬 변수 스택이 있는데 기본 타입 변수와 참조 타입 변수가 추가되거나 제거되고, 변수는 선언된 블록 안에서만 스택으로 존재하고 블록을 벗어나면 스텍에서 제거된다. 다만 배열 같은 경우에는 배열의 변수는 스택 영역에 생성되지만 배열의 데이터 자체는 Heap 영역에 생성되어 제거되지 않습니다. 즉 Java에서 배열은 객체로 취급을 합니다.
깊은복사 : 실제값을 새로운메모리 공간에 복사하는 것을 의미한다.
깊은 복사는 주소값을 참조하는 것이 아닌, 새로운 메모리 공간에 값을 복사하는 것이기 때문에 원본 배열이 변경되어도 복사된 배열에 전혀 상관이 없다.
따라서 배열을 복사한 후에 한쪽 값을 수정해도 다른 배열에 영향을 끼치지 않는다.
얕은복사 : 주소값을 복사하는 것을 의미한다.

각 인스턴스가 같은 메모리 상에 있는 주소를 가리키고 있기 때문에, 참조하는 영역의 데이터 값을 바꾸게 되면, 각 인스턴스의 값이 동시에 바뀐다. 이를 잘 생각하면서 코딩해야한다.

깊은복사를 진행하게 되면, Heap 메모리 공간에 새로운 영역을 할당하여 데이터를 갖도록 한다.
https://zzang9ha.tistory.com/372
https://velog.io/@ellyheetov/Shallow-Copy-VS-Deep-Copy
https://tangoblog.tistory.com/14
: (stack, heap)메모리 , JVM(https://tangoblog.tistory.com/14),