일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 주피터노트북 설치
- aws기본
- 리눅스기초
- AWS실습
- terraform with aws
- AWS CI/CD
- Linux
- linux명령어
- aws
- terraform따라하기
- blue/green배포
- 쉘스크립트
- 최소권한
- 리눅스기초명령어
- AWS CodeDeploy
- terraform기본
- aws따라하기
- aws기초
- AWS 공격테스트
- aws terraform
- opt/anaconda3/bin/jupyter_mac.command
- GDPR
- terraform기초
- AWS구축
- AWS배포자동화
- 리눅스
- cissp
- 직무분리
- Cissp sdlc
- 리눅스명령어
ysuekkom의 IT study note
[JAVA 이론] JVM의 메모리 구조와 메서드 동작 원리 본문
네트워크 백본망 관제 및 운용, 성능 개선을 위한 PKG 검증 및 기획 업무를 해왔어서 사실 JAVA나 C 등 프로그래밍언어를 다룰 일이 실무에서는 거의 없었다. 외부연동망 상태 감시 Tool 개발 TF 수행 시, 프로그래밍에 대한 필요성을 느꼈으나 급한 불 끄고 다시 살펴 볼 여력이 없었던... 프로그래밍!
제대로 공부해보자!(기본적인 내용은 생략하고, 메모리 내 동작 및 상속에 관해 이론정리 후 코딩 위주 실습 예정)
JVM이란?
JVM 메모리 모델 살펴보기
>>new Class create 시 내부 메모리 동작 확인하기
생성자 메서드에 대해 알아보자
-생성자 중복 정의 확인하기(Overloaing)
메서드의 오버로딩 알아보기
JVM이란?
Java Vritual Machine으로, 자바를 실행하기 위한 가상 머신으로 보면 된다.
OS에 종속받지 않기 때문에(JVM 가상 머신이 구동하니까) CPU가 JAVA를 인식하고, 실행할 수 있게 하는 것이 바로 JVM(가상머신)인 것이다.
즉, JAVA를 구동하기 위해서 필수요소이다.
즉 start.class라는 클래스를 생성하면, 해당 클래스를 바로 실행할 수 있는게 아니고,
클래스 파일을 JVM에 올리고 > 메모리에 로딩시키고 > 운영체제 플랫폼에 맞게 재 컴파일을 하는 구조다.
첫 번째 컴파일 수행 > 두 번째 컴파일 수행
즉 두 번의 컴파일이 이루어진다고 보면 된다.
- byte code: 중간어로, start.java파일을 컴파일하면, start.class파일이 생성되게 된다. == 1차 컴파일
- exe code: JVM이 각 OS에 맞는 실행코드로 변환하여 해당 OS에서 실행될 수 있게 한다. ==2차 컴파일
위와 같은 동작 방식으로, JAVA는 JVM으로 인해 OS에 종속되지 않고 실행할 수 있는 것이다.
JVM 메모리 모델
다음으로, JVM 메모리 영역에 대해 살펴보자.
- method area: 메서드의 바이트코드가 저장되는 영역으로 static keyword를 기준으로, static zone과 non-static zone으로 나뉘어져서 method area에 저장된다.
- stack area: 메서드를 실행(호출)하면 호출 정보가 저장되는 영역이다. method area에 메모리에 올라온 함수의 호출 정보가 기록되는 영역.(push) 변수와 파라미터, 연산과 리턴 값 등에 사용되는 '임시적인 값'이 생성 및 저장되는 영역이다. LIFO로, Last Input First Out으로 동작한다.
- heap area: new 연산자로 객체가 생성되는 영역이다.
실습으로 이해하기-1
main()내에서 변수의 합을 반환하는 add()함수를 선언 및 호출하는 간단한 클래스를 생성하는 예제로 JVM 메모리 구조와 동작방식을 알아보자.
public class ysuekkom{
public static void main(String[] args){
int a=10;
int b=20;
int sum = add(a,b); //add 함수 호출, return 값을 sum 변수에 대입
System.out.println(sum); //sum 변수값 출력
public static int add(int a, int b){
int sum=a+b;
return sum;
}
}
위와 같은 간단한 예제를 실행하게 되면, JVM의 각 메모리 영역에서는 아래와 같이 동작한다.
static으로 선언된 메서드는 메모리에 자동으로 로딩되며, method area의 static-zone에 저장되어 레이블이 부여된다.
1. public "static" void main() >> method area의 static zone에 mian() 로딩
2. main() 내에 있는 add() 호출
3. method area의 static zone에 add() 로딩
4. main()이 호출되면서 Stack area에 main()메서드의 호출 정보가 저장됨(첫 번째로)
5. add()이 호출되면서 Stack area에 add()메서드의 호출 정보가 저장됨(두 번째로)
6. Statc area영역은 LIFO로 동작, 나중에 들어온 add() 수행 후 리턴값 반환 후 종료 ((Stack area에 main()메서드의 호출 정보 폐기(삭제됨))
7. 반환 받은 리턴값을 통해 main()메서드 동작 후 종료(Stack area에 main()메서드의 호출 정보 폐기(삭제됨))
실습으로 이해하기-2
main()내에서 새로운 객체를 생성하여, 변수의 합을 반환하는 add()함수를 호출하는 간단한 클래스를 생성하는 예제로 JVM 메모리 구조와 동작방식을 알아보자.
public class ysuekkom8915{
public static void main(String[] args){
int a=10;
int b=20;
ysuekkom ysue=new ysuekkom();
int sum = ysue.add(a,b);
System.out.pringln(sum);
}
public int add(int x, int y){
int sum = a+b;
return sum;
}
}
main() 내에서 신규 객체가 생성되면, new연산자에 의해 heap area을 사용하게 된다. 또한 add()가 static으로 선언되지 않았으므로 method area 내 non-static zone 영역에 올라가는 것을 확인할 수 있다.
단계별 동작을 확인해보자.
1. main()클래스가 컴파일 되면, 메서드 영역 내 static zone에 메인클래스가 자동으로 로딩
2. 메서드 영역에 올라간 메인클래스가 호출되면서 statck area에 main()의 호출정보 로딩
3-4. main()내에서 new 연산자를 사용, 객체를 생성하면서 heap area에 로딩
5. add()가 non-static zone에 로딩
6. add()의 호출정보가 statck area에 로딩
이후 동작은 위에서 먼저 살펴본 실습1과 동일하다. add()의 연산이 끝나면 값을 리턴하면서 add()호출정보는 statck area에서 삭제되고,
이후 mian()에서 sum을 출력하고 종료되면서 statck area에 있는 main() 호출 정보도 삭제되게 된다.
생성자 메서드(Constructor)
객체를 생성하게되면 생성자 메서드가 자동으로 생성된다! 생성자 메서드의 역할은 무엇일까? 알아보자.
- 객체를 생성할 때 자동으로(default) 생성되는 메서드로, 객체 생성 후 초기화 역할을 수행
- 클래스 이름과 동일한 이름으로 생성자 메서드가 생성됨
- 생성자 메서드를 따로 정의할 경우, 기본 생성자를 명시해줘야 함
- 클래스 중복정의에 반드시 필요한 개념으로 중요함
public class KkomiFriends{
public String name;
public int age;
public String DogBreed;
}
KkomiFriends ff=new KkomiFriends(); //객체 생성
/*
public KkomiFriends(){ //코드상에 보이지 않아도 자동 생성됨=기본생성자 메서드
super();
}
*/
위 예제에서 KkomiFriends를 생성하면 아래 주석과 같이 코드상에는 보이지 않아도 기본생성자로 생성된다.
다만 생성자를 중복 정의하게 되면(직접 초기화 작성), 기본 생성자는 명시해줘야한다.
또한 privatedmfh 객체를 보호할 경우, setter, getter메서드를 통해 데이터를 가져온다.
메서드 오버로딩(Overloading)
메소드 오버로딩이란 무엇일까?
메소드를 중복 정의, 즉 같은 이름의 메소드를 여러개 정의하는 것을 말한다. 다만, 이름은 같아도 매개변수의 type과 갯수가 다른 것으로 구분한다.
이름이 같다면 컴파일 시 어떻게 구분하여 내가 사용하려고 하는 메소드를 그대로 가져올 수 있을까?
컴파일러가 메소드를 컴파일 할 때, 매개변수의 유형 즉 type(=int, String, floate 등)을 기록하기 때문에 구분 가능하다. 위에서 언급했듯 타입과 갯수가 달라야 같은 이름의 메소드로 중복정의 할 수 있기 때문이다.
즉, 컴파일 시점에서 호출 될 메소드가 이미 결정되어 있는 것이라 호출이나 속도에 관계없이 메소드를 불러와 동작한다. ==정적바인딩
(>>상속에 대한 내용을 포스팅 후, 동적바인딩에 대한 내용과 비교 설명 할 예정)
public class Overloading_Test(){
public static void main(String[] args){
Overloading ov = new Overloading();
ov.sum(10, 20); //30
ov.sum(9.5f, 20.5f); //30
ov.sum(9.5f, 20); //29.5
}
public class Overloading{
public void sum(int x, int y){ //컴파일러 내에 저장된 이름: sum_int_int
System.out.println(x+y);
}
public void sum(float x, float y){ //컴파일러 내에 저장된 이름: sum_float_float
System.out.println(x+y);
}
public void sum(float x, int y){ //컴파일러 내에 저장된 이름: sum_float_int
System.out.println(x+y);
}
}
마치며
상속에 대한 개념이 아주 중요하다. 다음 포스팅에서는 상속에 대한 내용을 포스팅 하겠다~!!
'Language > JAVA' 카테고리의 다른 글
[Spring Boot] macOS 스프링부트/이클립스 설치 및 롬복(Lombok) 연동하기 (0) | 2023.07.19 |
---|---|
macOS JAVA 설치 및 환경변수 설정하기 / Visual Studio 팩 추가하기 (0) | 2023.07.19 |