반응형

Class 파일은 실행 시 Link를 할 수 있도록 Symbolic Reference 만을 가지고 있다.

Runtime 시점에 실제 물리적인 주소로 대체되는 작업인 Dynamic Linking이 일어나게 된다.



Class-File-Format은 Network-Byte-Order 를 사용하기 때문에 Big-Endian 방식을 사용하게 된다.


메모리 주소값을 할당하는 방식을 Network-Byte-Order 를 사용하는데 Big-Endian을 사용하기로 약속되어있고, 서로 다른 계열의 CPU끼리 데이터를 전송받을 때의 문제점을 해결하기 위해 정해진 일종의 약속이다.


  • Gabage-Collector
    • Gabage-Collection을 통해 Heap이나 Method-Area의 사용되지 않는 Object를 Memory에서 삭제한다.
    • HotspotJVM은 Heap을 Young-Generation과 Old-Generation으로 나누어 사용한다.
    • Young-Generation은 Eden영역과 Survivor영역이 존재한다. 객체가 Eden영역으로 처음 Allocation 되며 자주 사용되던 객체가 Old영역으로 가기 전에 Survivor 영역으로 이동하게 된다.
    • Old-Generation은 성숙된 객체들이 Promotion 되는 장소이다.
    • Minor-GC는 Young-Generation에서 발생, Promotion이 발생...
    • Major-GC는 Old-Generation에서 발생, Minor-GC를 통해서 발생할 수도 있음...
    • Full-GC는 너무많은 클래스 로딩으로 Permanent-Area가 부족하게 되어 발생할 수 있음...
    • 잘못하면 suspend-time이 길어져 Stop-The-World 방식의 Compaction으로 회귀할 수 밖에 없음.
  • Gabage-First-Collector
    • Generation 구분을 없애고 Region 으로 재편하였다. 논리적인 구분?
    • 물리적인 Young/Old 영역에서의 Allocation/Promotion 대신 Gabage로만 꽉 차 있는 Region부터 Collection을 시작한다고해서 붙여진 이름이다.
    • G1 Collector는 철저하게 Region 단위로 Gabaga-Collection 이 발생한다. 따라서 Suspend 현상도 Region을 사용하는 Thread에 국한된다.
  • Calss-Loader
    • JVM 안으로 Class를 Load 하고 Link를 통해 적절히 배치하는 일련의 작업을 수행하는 모듈.
    • *.class 파일들을 Runtime-Data-Area 에 적재한다.
    • Bootstrap-Class-Loader(jre/lib/rt.jar), Extention-Class-Loader(jre/lib/ext), Application-Class-Loader(System-Class-Loader, User-Defined-Class-Loader)
    • java5부터 Class-Sharing 제공...
    • Load-Time-Dynamic-Loading과 Runtime-Dynamic-Loading 이 있다...
    • Class-Loader-Work 는 Loading, Linking, Initialization의 세가지 과정이 있다. 클래스파일이 검증을 거쳐 symbolic-reference 가 direct-reference 로 변경되는 과정이다.
  • Executor-Engine
    • Load된 Class의 Bytecode를 실행하는 Runtime-Module이다.
    • 모든 ByteCodes를 Interpreter 방식으로 처리하여 초기의 JVM은 실행속도에 있어서 약점을 가지고 있었는데,  JIT(Just-In-Time) Compiler 방식이 등장하여 문제점을 보완하였다.
    • JIT(Just-In-Time) Compiler 는 Bytecodes 를 NativeCode로 Compile하여 실행시간을 빠르게 하였다. 보통 두 방식을 섞어서 쓴다(Lazy Fashion).
    • loop 와 다차원배열 처리에 성능적으로 약함...


  • Runtime-Data-Area
    • Process로서의 JVM을 수행하기 위해 OS로부터 할당받는 메모리 영역.
    • PC Register, Java Virtual Machine Stacks, Method Area, Heap, Native Method Stacks.
    • PC Register
      • 각 Thread마다 하나씩 존재하며 Thread가 시작할 때 생성된다. Stack-Base로 작동하며 현재 수행중인 JVM 명령어를 가지게 된다.
    • Java Virtual Machine Stacks
      • 각 Thread마다 하나씩 존재하며 Thread가 시작할 때 생성된다. 여러 Stack-Frame들이 있고 현재 수행하고 있는 Method의 정보를 저장하는 것을 Current-Frame 이라고 한다.
      • Stack-Frame은 Local-Variable-Section, Operand-Stack, Frame-Data 세 부분으로 되어 있다.
    • Native Method Stacks
      • 각 Thread마다 하나씩 존재하며 Thread가 시작할 때 생성된다. Native-Code로 호출한 메소드에 대한 Stack 영역.
    • Method Area
      • 모든 Thread들이 공유하는 메모리 영역이다.  JVM이 기동할 때 생성이 되며, Garbage-Collection의 대상이 된다. ClassLoader에게 넘겨받은 ClassFile에서 Type 관련 정보를 추출하여 저장하게 된다. Type-Information, Constant-Pool, Field-Information, Method-Information, Class-Variable, ReferenceToClass-ClassLoader, ReferenceToClass-Class, Method-Table.
    • Heap
      • 모든 Thread들에 의해 공유된다. 메모리 해제는 Gabage-Collection을 통해서 이루어지고, Instance(Object)와 Array객체 두 가지 종류만 저장되는 공간일 뿐이다. 실제 구현에 대해서는 각 벤더에게 위임하였다. HotspotJVM이나 IBM-JVM의 Object-Layout과 Heap 구조를 통해 JVM의 Heap에 대한 전반적인 이해를 하는 것이 의미있을 것이다.

Class와 Instance의 관계

Java 관련 서적을 보면 Class와 Instance를 붕어빵틀과 붕어빵으로 표현하는데, 이것은 좋은 비유라고 생각한다. Class가 Loading 되면 Method-Area 에는 Java로 작성한 Code에서 Class의 속성들을 추철하여 정보화되어 기록된다. 다시 말해 하나의 틀이 만들어지는 셈이다. 이를 테면 이 Class는 이러이러한 Method가 있고 이 내용은 어떠하여 변수는 어떤 것을 가진다는 정보가 MethodArea에서 생성된다.

 만약 누군가가 이 Class에 대한 Instance를 하나 생성하려고 한다면 Method Area의 Class 정보를 틀로 하여 Heap에 Object를 하나 찍어낸다. 이것이 Instance이고 여기에 실제 변수에 대한 실제 메모리 상의 주소 등을 포함하여 사용하게 되는 것이다.

 Member Variable(Instance Variable)의 경우는 Heap에 생성된 Instance에 그 값이 저장되고 Class Variable은 이 Class 정보가 있는 Method Area, 더 정확하게는 Class Variable에 저장된다.


  • Thread...
    • Native Thread 를 White-Thread로 부르고, JVM의 Thread를 Green-Thread라고 부르던 때가 있었다...(JAVA 1.1)
    • JAVA1.2부터 ... 둘이 혼용된 Thread-Model ...
    • JAVA1.3부터 결국엔 Native 가 Default-Thread-Model...
    • GreenThread는 MultiProcessSystem에서 이점을 가질 수 없었다...

Synchronization이 필요한 지역을 Critical-Section이라 하고, Thread가 Critical-Section에 들어가면 반드시 Synchronization 작업을 수행하게 된다. 바꾸어 말하면 Thread 가 Critical-Section에 들어가기 위해서는 Lock을 요청하는 것이고 이 Critical-Section은 Synchronization으로 보호되고 있다고 할 수 있다.


- Object Header에 lock-counter를 통해서 알 수 있다...





반응형

+ Recent posts