일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- AAC
- 플로이드워셜
- 상태관리
- 디자인 패턴
- 프로세스
- http 역사
- 내부 단편화
- http발전과정
- apk 빌드 과정
- 리사이클러뷰풀
- recyclerview
- flutter
- GetX
- AsyncListDiffer
- DiffUtil
- 뷰홀더
- Kotlin
- 자이고트
- 데코레이터 패턴
- 물리 메모리
- 안드로이드
- Dispatchers
- Android
- 리사이클러뷰
- 절대 주소
- NestedScrollView
- viewModelScope
- appcompatacitivity
- appcompatactivity
- 운영체제
- Today
- Total
hong's android
[Java] 자바와 Jvm에 대해서 본문
자바는 jvm이라는 가상머신 덕분에 플랫폼(os) 독립적이다. 보통 c 나 c++ 같은 언어는 프로그램을 개발했던 환경에서만 정상적으로 실행할 수 있다. 해당 기계어로 변환되어 있기 때문이다. 반면 자바는 프로그램을 개발했던 환경에 구애받지 않고 어떠한 환경에서도 정상적으로 작동이 된다. 자바는 .class 라는 바이트 코드를 jvm에서 기계어로 변환하는 과정을 거치는데 이 과정에서 jvm은 해당 os에 맞는 기계어로 번역해 주기 때문이다.
Jvm 동작 원리
1. 자바소스를 컴파일 자바 컴파일러에 의해 바이트 코드(. class )로 컴파일된다.
2. 객체?를 참조할 때 classLoader는 동적로딩을 통해서 필요한 클래스를 JVM 메모리에 올린다.
3. 실행엔진(Execution Engine)에 의해서 JVM메모리에 올라와있는 코드를 번역해서 실행한다.
Jvm 전체 구조
Class Loader
바이트 코드를 jvm 메모리에 적재해주는 역할, 클래스에 대한 참조가 일어날 때
Execution Engine
바이트 코드를 실행할 수 있는 기계어로 번역해주는 역할. Jit 방식 사용
Garbage Collector
Runtime Data Area의 힙 영역에서 불 필요한 객체(참조관계가 끊어진 객체들)를 회수해주는 역할
Runtime Data Area
jvm이 프로그램을 실행하기 위해 os로부터 할당받은 메모리
Method area
클래스 로더가 적재한 클래스, 인터페이스, static 변수 정보들
Heap area
인스턴스와 배열이 담긴다.
Stack area
메서드가 호출될 때 메서드의 지역변수, 매개변수, return주소, 임시 변수 등의 정보가 담긴다. + object의 참조값
PC Register
스레드가 생성될 때마다 생성되는 영역으로, 현재 수행 중인 jvm 명령의 주소값
Native method stack
자바 이외의 언어로 작성된 네이티브 코드들을 위한 stack
gc(garbage collector)란?
사용하지 않는다고 판단하는 객체를 알아서 메모리에서 해제시켜주는 놈이다.
gc가 왜 생겼을까?
자바 이전에는 개발자가 메모리를 직접 관리했다. 하지만 직접 관리하기 불편하고 잘못 관리를 했을 때 메모리누수가 생기기도 한다. 그렇기에 메모리를 자동으로 관리해 주는 gc가 나오게 됐다.
gc의 쓰레기 객체를 어떻게 회수할까?
객체에 대한 참조가 끊어지면 , Unreachable Object로 판단되고 객체가 회수된다.
1.Mark(reachable Object 탐색 후 mark) -> 2.Sweep(mark 되지 않은 객체 회수)
([Java] Garbage Collector 글 참고)
그럼 gc가 항상 일어나면 좋은 거 아닌가?
gc가 일어날 때 mark 과정에서 gc를 수행하는 스레드 외에 모든 스레드가 종료되기 때문에 계속 수행하는 경우 자원이 낭비된다.
자바가 다른 언어보다 느리다고 하는 이유는 뭘까?
1.JVM
c, c++은 코드를 바로 os가 해석할 수 있는 기계어로 변환한다. 반면
자바는 다양한 플랫폼(os)에 독립적이기 위해서 jvm을 사용한다. 그렇기에 자바 코드를 실행하면 바이트 코드로 컴파일된 후, 동적 할당 된 코드를 Excution Engine이 번역해서 실행하게 된다. 바로 기계어로 번역을 하는 것이 아니기 때문에 비교적 더 느리다.
또한 동적할당된 코드를 Excution Engine에서 번역을 할 때 인터프리터 식으로 바이트 단위로 하나씩 번역을 하기 때문에 느리다. 그래서 jit와 같은 방식을 사용해서 속도를 높였지만 비교적 느리다.
*Jit
Jit는 반복적으로 사용되는 코드들을 따로 저장해놓고 인터프리터로 해석을 하다 반복되는 부분은 이미 번역 해놓은 코드를 사용한다.
2. 객체 지향 언어
객체 지향 특성상 메서드또는 변수를 사용하기 위해선 하나의 클래스, 객체를생성해야 한다. 이를해결하기 위해 static이 존재한다. 하지만 static은 객체 간 독립성을 추구하는 객체 지향적 철학에 어긋나고 항상 메모리를 점유하고 있기 때문에 단점이 존재한다. 그렇기에 정적으로 컴파일하는 경우많은 불필요한 코드들이 메모리에올라가게 되고 런타임에 동적으로 객체가필요할 때 메모리에 올리게 된다.
위 단점들을 가지고 굳이 객체지향을 사용하는 이유는 뭘까?
1. 재사용성과 확장성이 좋습니다.
2. 클래스 단위로 나누어져 있어 모듈화 되어있어 클래스를 재 사용하기 편합니다.
3. 절차식 언어보다 비교적 의존성이 줄어들고객체 간 독립성이 유지된다면 유지보수하기 편합니다.
+ Constant pool
Java Class File의 구성 항목 중 하나인 Constant pool은 리터럴 상수 값을 저장하는 곳이다. 여기에는 String 뿐 아니라, 모든 종류의 숫자, 문자열, 식별자 이름, Class 및 Method에 대한 참조와 같은 값이 포함된다. Constant pool은 특정 상수에 대한 모든 인덱스 또는 참조를 16비트(type u2) 번호로 제공된다. JVM은 Runtime Constant Pool을 통해 해당 메서드나 필드의 실제 메모리 상 주소를 찾아 참조한다.
Reference.
https://blog.breakingthat.com/2018/12/21/java-constant-pool과-string-pool/
Java – Constant pool과 String pool – 조금 늦은, IT 관습 넘기 (JS.Kim)
> String 리터럴에 대한 의문 아래와 같은 코드를 보자. public class StringPoolTest { public static void main(String[] args) { StringPoolTest spt = new StringPoolTest(); spt.stringTest("HelloWorld"); } public void stringTest(String helloW
blog.breakingthat.com
https://www.baeldung.com/jvm-constant-pool
'Develop > Java' 카테고리의 다른 글
[Java] 자바 정리 (0) | 2022.12.31 |
---|---|
[Java] Map 인터페이스 (0) | 2022.12.31 |
[Java] DeadLock (0) | 2022.12.20 |
[Java] java.lang.String 클래스에 대해서 (0) | 2022.12.20 |
[Java] Abstract class VS Interface (0) | 2022.12.20 |