JVM의 자바 메모리 관리
JVM
- JVM은 컴퓨터가 자바 프로그램을 실행하는 데 사용되는 가상 머신이다.
- JVM은 메모리 관리를 자동으로 처리하여 자바 애플리케이션의 성능을 최적화한다.
- 메모리 관리는 Xms와 Xmx라는 JVM 옵션을 사용한다.
- JVM 메모리 구조
- Heap 메모리
- 모든 자바 클래스, 인스턴스와 배열이 할당되는 메모리 = 런타임 데이터 영역
- Heap의 최초 크기 -Xms VM옵션으로 정의
- 최대 Heap크기 -Xmx 옵션으로 설정 ( 기본적으로 최대 Heap크기는 64MB로 설정 )
- Heap은 가비지컬텍터 전략에 따라 고정된 크기, 동적크기가 가능
- Non-Heap 메모리
- JVM 시작할 때 생성되며 클래스당 구조체(런타임 상수풀, 필드, 함수 데이터, 함수와 생성자 코드, 고정 문자열과 같은 것)를 저장
- -XX:MaxPermSize VM 옵션으로 변경
- Other 메모리
- JVM 코드 자체, JVM 내부 구조체, 로딩된 프로파일러 에이전트 코드, 데이터 등을 저장
- Heap 메모리
- JVM 메모리 구조
자바의 데이터형
- 기본형(primitive type) : Boolean Type(boolean), Numeric Type(short, int, long, float, double, char)
- 참조형(reference type) : Class Type, Interface Type, Array Type, Enum Type, 기본형을 제외한 모든 것들
- 기본형 (int, double, boolean 등)은 stack의 변수 안에 value 저장
- 참조형 (Integer, Obejct, Array, Map 등) 은 stakc의 변수 값에는 객체의 주소 값, 객체는 별도의 Heap영역에 저장
Call by Value & Call by Reference
Call by Value는 함수의 인자를 전달할 때 값을 전달하는 방식
Call by Reference는 주소를 전달하는 방식
Call by Value
- 메소드를 호출할 때 넘겨 주고 싶은 인자를 지정하면, 메소드의 매개 변수가 지정한 변수 값의 복사본으로 초기화되는 것이다.
- 따라서 함수 내에서의 변경은 메소드를 호출할 때 지정한 변수(원본)에 아무 영향을 미치지 않는다.
- 자바는 Call by value방식을 사용한다!
Call by Reference
- 메소드를 호출할 때 넘겨 주고 싶은 인자를 지정하면, 메소드의 매개 변수가 지정한 변수의 레퍼런스로 초기화되는 것이다.
- 따라서 함수 내에서의 변경은 메소드를 호출할 때 지정한 변수(원본)에 영향을 미친다.
method1에선 a=10, b=5의 값을 전달했고 method2에선 이 값을 a=20, b=10으로 바꿔서 사용
method2를 마치고 돌아왔을 때 method1에서는 a=10, b=5 이 결과로 나온다.
=> call by value를 사용했기 때문!
자바에서는 call by value를 사용할때, 넘겨받은 메소드에서 값을 복사하여 새로운 지역변수에 저장!
이 때 Method2는 Method1의 변수를 사용한 것이 아니라, 자신이 새롭게 생성한 지역 변수에 Method1의 변수 이름과 변수 값을 복사하여 사용하는 것
만일 call by reference방식을 사용했다면 a,b의 값에 영향을 미친다
예외 경우
public class JavaIsCallByValue {
public static void main(String[] args) {
Num numA = new Num(1);
Num numB = new Num(3);
System.out.println("swap 전 numA:" + numA.num + " " + "numB:" + numB.num);
swap(numA, numB);
System.out.println("swap 후 numA:" + numA.num + " " + "numB:" + numB.num);
}
private static void swap(Num numX, Num numY) {
Num tmp = numX;
numX = numY;
numY = tmp;
}
public static class Num {
int num;
public Num(int num) {
this.num = num;
}
}
}
public class JavaIsCallByValue {
public static void main(String[] args) {
Num numA = new Num(1);
Num numB = new Num(3);
System.out.println("swap 전 numA:" + numA.num + " " + "numB:" + numB.num);
swap(numA, numB);
System.out.println("swap 후 numA:" + numA.num + " " + "numB:" + numB.num);
}
private static void swap(Num numX, Num numY) {
int tmp = numX.num;
numX.num = numY.num;
numY.num = tmp;
}
public static class Num {
int num;
public Num(int num) {
this.num = num;
}
}
}
값이 변경된 이유
- 자바가 함수의 인자로 전달해주는 것은 복사된 참조 값을 전달하기 때문
- 즉, 참조값을 받아서 그 참조값을 이용하는 것은 가능하기에 각각의 필드값이 변경
'🍎 Backend > JAVA' 카테고리의 다른 글
[java] abstract(추상) vs implements의 비교 (1) | 2024.12.20 |
---|---|
[JAVA] 해시 맵 (0) | 2023.12.11 |
[Java] 컴파일 과정 (0) | 2023.12.04 |
자바 기초 (0) | 2023.03.02 |
[JAVA] 클래스와 객체 (0) | 2023.02.05 |