JAVA의 메모리 영역 <메소드/스택/힙>
- 메소드 : 바이트 코드, 전역변수, static변수
- 스택 : 매개변수, 지역변수 (사용 종료 시 바로 소멸, 컴파일 시 메모리 할당)
- 힙 : new로 생성된 객체 (호출 끝나도 사라지지 않음, 프로그램 실행 시 동적할당)
자바 프로그램 실행과정
1) JVM : OS로부터 프로그램이 필요로 하는 메모리 할당받음
2) javac (자바 컴파일러)가 소스코드(.java)를 읽어 바이트코드(.class)로 변환시킴 (컴파일)
3) 클래스로더 : class 파일들 JVM으로 로딩
4) 실행엔진 : 로딩된 class 파일들 해석 (class 실행)
5) 해석된 바이트코드 > 런타임 데이터 영역에 배치 (실질적 수행)
위 과정 중에 JVM은 GC작업 수행 (스레드 동기화 등)
JVM (자바 가상 머신)
JAVA가 OS에 구애받지 않고 재사용 가능하게 함 (중개자 역할 : JAVA - JVM - OS )
자바 애플리케이션을 클래스 로더로 읽어 자바 API와 함께 실행 (스택기반 가상머신)
역할 : 메모리관리, 가비지 컬렉션
JVM 구성
1) 클래스로더 : JVM으로 클래스파일 로드, 링크를 통해 배치, 런타임 시 동적으로 클래스 로드, 컴파일러 역할
2) 실행엔진 : 클래스로더가 런타임 영역에 배치한 바이트코드를 실행 가능한 형태로 변경, 실행
- 인터프리터 : 한 줄씩 수행 (느림)
- JIT (just-in-time) : 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체 컴파일 > 네이티브 코드로 변경 > 네이티브 코드로 실행 (네이티브 코드 : 캐시 보관, 한 번 컴파일된 코드 빠른 수행)
- 네이티브 코드 : 자주 수행되는 메소드를 JVM->실행엔진->JIT 컴파일
3) 가비지 컬렉터 : 가비지 컬렉션
4) 런타임데이터영역 : JVM의 메모리영역. 자바 애플리케이션을 실행할 때 사용하는 데이터들을 적재하는 영역
- 메소드 영역 : 모든 쓰레드가 공유하는 영역 (클래스, 인터페이스, 메소드, 필드, static 변수 등 바이트코드 보관)
- 힙 영역 : 모든 쓰레드가 공유하는 영역 (new로 생성된 객체/배열. GC가 참조되지 않는 메모리를 제거하는 영역)
- 스택 영역 : 메소드 호출 시마다 생성되는 영역 (메소드 내 매개변수, 지역변수 등을 임시로 저장. 메소드 끝날때 삭제)
- PC 레지스터 : 쓰레드 시작될 때마다 각각 생성 (쓰레드가 어떤 명령을 실행할지 기록, 수행중인 JVM 명령의 주소를 가짐)
- 네이티브 메소드 스택 : 자바 외 언어로 작성된 코드를 위한 영역
가비지 컬렉션 (GC)
가비지 정리 프로그램 (가비지 : 정리되지 않은 메모리, 유효하지 않은 메모리주소)
참조되지 않은 객체 해제, 가용 공간 만듦 > heap 메모리 재활용을 위해
자동 메모리 정리로 개발자의 개발 속도 향상
*Mark : 스택의 모든 변수를 스캔, 각각 어떤 오브젝트를 레퍼런스 하고있는지 찾는 과정
*Sweep : Mark되지 않은 모든 오브젝트들을 heap에서 제거
문제점 : 메모리를 되찾을 시점을 결정하기 위한 오버헤드 발생 가능
JRE (Java Runtime Environment) : 자바 실행환경
JVM이 자바 프로그램을 동작시킬 때 필요한 라이브러리, 기타 파일들을 가지고 있음
JVM + 자바 클래스 라이브러리 + 자바 명령(command) + 기타인프라를 포함한 디렉토리 (패키지)
- bin/ : Java 실행 프로그램, JVM 시작하는 java (javaw,,), keytool, policytool 등
- conf/ : 사용자가 편집가능한 파일
- lib/ : supporting 파일, .jar 구성파일, 속성, 글꼴, 인증서, .class 포함 모듈
- 네이티브 바이너리 코드 지원 : .dill (Window), dylib (Mac), .so (Linux)
JDK (Java Development Kit) : JRE+개발도구들 (javac, jdb, java, etc...)
Java용 SDK (Software Development Kit) => 프로그램 생성, 컴파일 가능
JRE의 상위 집합 디렉터리 세트
- bin/ : 개발도구로 확대 - javac (.jar, javadoc, jshell)
- jmods/ 추가
일반적으로 Java 프로그램 실행 = JRE만 있으면 됨.
Java 프로그래밍 = JDK 설치 필요
애플리케이션 서버 = JSP 를 Java Servlet으로 변환 >> JDK를 사용해서 Servlet 컴파일 해야함
>>> JDK 설치 필요
Runtime Data Area
프로그램 수행을 위해 OS에서 할당받은 메모리 공간
구성
1) PC : 프로그램 카운터 레지스터, 스레드 시작 될 때 생성됨. (1스레드 1PC) 현재 수행중인 JVM 명령 주소 가짐
2) JVM stack : 프로그램 실행 중 소멸되는 특성의 데이터 임시저장, 삭제 (임시 할당, 변수, 임시데이터, 스레드, 메소드 등)
3) Native Method stack : 실제 실행가능한 기계어 프로그램 실행 영역, JAVA 외의 언어로 작성된 코드를 바이트코드로 전환, 저장
4) Method Area (=Class area = Static area) : 클래스 정보를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장
(Runtime Constant Pool : 상수 자료형 저장, 참조/ 중복 방지)
5) Heap : new연산으로 생성된 객체, 배열을 저장하는 가상 메모리 공간
*오버로딩과 오버라이딩
- 오버로딩 : 메소드의 이름은 같고, 매개변수를 다르게 함으로써 여러 메소드를 만드는 것
- 오버라이딩 : 부모클래스로부터 상속받은 메소드를 재정의하는 것. 자식 객체에서 오버라이딩한 메소드는 호출시 오버라이딩한 메소드가 우선시 되어 호출됨 (동일한 리턴타입, 메소드 이름, 매개변수를 가져야함)
*추상클래스와 인터페이스
- 추상클래스 : 클래스 내에 추상 메소드가 하나 이상 포함되거나 abstract로 정의된 경우. extends를 통해 기능을 이용하고 확장하도록 하는 클래스
- 인터페이스 : 모든 메소드가 추상 메소드인 경우 (여러 implements가 가능해 다중 상속 구현 가능) 뼈대만 있으며, 구현하는 모든 클래스에 대해 강제적으로 메소드를 구현하도록 만듬
*메모리, 성능 개선 방법
- 인스턴스 변수에 접근할 일이 없으면, static 메소드를 선언하여 호출
- 모든 객체가 서로 공유할 수 있기 때문에 메모리가 절약되고 연속적으로 그 값의 흐름을 이어갈 수 있는 장점이 존재
*클래스와 구조체의 차이
- 구조체 : 여러 자료형의 변수들을 하나의 구조로 묶을 수 있는 자료구조.
- 클래스 : 변수뿐만 아니라, 메소드도 포함시킬 수 있음
- 구조체도 함수 포인터를 이용하면 클래스처럼 만들어 낼 수도 있다.
*스레드 생성, 장단점
- 생성 : Runnable(인터페이스)로 선언되어 있는 클래스 or Thread 클래스를 상속받아 run() 메소드를 구현
- 장점 : 빠른 프로세스 생성, 메모리를 적게 사용 가능, 정보 공유가 쉬움
- 단점 : 데드락에 빠질 위험이 존재
*벡터와 배열
- 벡터 : 동기식. 한 스레드가 벡터 작업 중이면 다른 스레드가 벡터 보유 불가능
- 배열리스트 : 비동기식. 여러 스레드가 배열리스트에서 동시 작업이 가능
Reference
'Program Language > Java' 카테고리의 다른 글
[OOP] 캡슐화, 추상화, 상속, 다형성, 상속, 동적 바인딩 (0) | 2021.05.07 |
---|