πŸ’»
Albert's Til
GitHub
  • 맀일맀일 μ‘°κΈˆμ”© μ„±μž₯ν•˜κΈ°
    • README
    • CS
      • Network
      • HTTP
        • NO-CACHE
      • 였λ₯˜ μ½”λ“œ
      • ORM 도ꡬ
      • Design Pattern
        • CQRS Pattern
          • Event Sourcing and CQRS pattern
        • Builder Pattern
    • DB
      • MySQL
        • Timeline
        • Pagination
        • Index
        • Database Performance Optimization Strategies
        • B+ tree
        • MySQL Connectors VS MySQL Shell(Scripting) VS MySQL Workbench
        • MySQL Storage Engine Architecture
      • Normalization & Denormalization
      • JPA
        • @Transactional
        • Why JPA?
        • About JPA
        • N+1 Issue
        • Index
        • ElementCollection&CollectionTable
        • orphanRemoval
        • CascadeType
        • Use Subselect
        • Dynamic Instance Creation
        • Paging
        • Order
        • Spefication
        • mappedBy
      • MongoDB
        • ObjectId
      • Why MySQL?
      • ACID properties of transactions
      • Between JPA and JDBC
      • Identifiers in Hibernate/JPA
    • Java
      • Jackson de/serialize
      • Collections.singletonList() vs List.of()
      • Manage dependencies in Gradle
      • Logging Level
      • Bean Validation
      • JVM Internals
        • Threads
          • Frame
        • Shared Between Threads
          • Classloader
            • Class Loader Hierarchy
            • Loading Linking Initialization
      • Java Collection Framework
      • Annotation
      • Generic
      • λ””λ―Έν„° 법칙
    • Spring
      • Caching
      • Spring Integration Overview
        • ThreadPollTaskExecutor
        • Messaging Bridge
        • Channel Adapter
        • Poller
        • Configuration and @EnableIntegration
        • Message Endpoints
        • Message Channels
      • HATEOAS
      • @Autowired vs Constructor Dependency Injection
      • Spring Security
        • JWT 토큰 μ‚¬μš©ν•œ 인가
        • OAuth 2 Login
        • OAuth 2 인증
        • 인가
        • 인증
        • PasswordEncoder
      • IoC Container
      • Filter,Interceptor,AOP,Argument Resolver
      • Spring Annotation
      • About Spring
    • Kafka
      • Error Channel
    • Infra
      • Scale Up || Scale Out
      • Docker
        • Dockerfile
        • Docker Hub Deploy
        • Command
      • Cloud μœ ν˜•
        • Infrastructure as a Service
        • Platform as a Service
        • Software as a Service
      • 무쀑단 배포
        • μ—”μ§„μ—‘μŠ€(Nginx)
      • μ½”λ“œ μžλ™ 배포
        • Technical
      • AWS EC2
        • PEM(Privacy Enhanced Mail) ν‚€
      • AWS RDS
      • AWS S3
    • CodeSquad
      • Spring Boot Project 1μ£Όμ°¨ 회고
      • Spring Boot Project 2μ£Όμ°¨ 회고
      • Spirng Boot Project 3μ£Όμ°¨ 회고
      • Spring Boot Project 4μ£Όμ°¨ 회고
    • Foody Moody ν”„λ‘œμ νŠΈ
      • Query Performance Comparison
      • HeartCount Asynchronous Issue
      • DeferredResult
      • ResponseBodyEmitter
      • SseEmitter (Spring)
      • Server-Sent Events (SSE)
      • 기술 μŠ€νƒ 적용 이유
      • NO-CACHE(HTTP)
      • Transactional
    • DDD
      • AggregateId
    • Test
      • RestAssured
    • Coding and Algorithmic Problems
      • 819. Most Common Word
      • 344. Reverse String
      • 125. Valid Palindrome
      • 937. Reorder Data in Log Files
    • Node
      • Async... Await...
      • Custom Transactional Decorator Challenger
    • Python
      • Python Basic Grammar
        • Comments and Input/Output
        • Variable
        • Data type
        • Operations and syntax
        • List,Tuple,Dictionary,Set
        • Function
        • Conditional statement
        • Loop
    • HTML
      • HTML Basic
      • HTML Basic Tags
      • HTML Form Tags
      • HTML Table Tags
    • CSS
      • CSS Basic
      • CSS Practice
Powered by GitBook
On this page
  • Heap
  • Memory Management
  • Non-Heap Memory
  • Just In Time (JIT) Compliation
  • Method Area
  • Class File Structure
  • Classloader
  • Faster Class Loading
  • Where Is The Method Area
  • Classloader Reference
  • Run Time Constant Pool
  • Exception Table
  • Symbol Table
  • Interned Strings (String Table)

Was this helpful?

  1. 맀일맀일 μ‘°κΈˆμ”© μ„±μž₯ν•˜κΈ°
  2. Java
  3. JVM Internals

Shared Between Threads

Heap

Heap은 λŸ°νƒ€μž„μ— 클래슀 μΈμŠ€ν„΄μŠ€μ™€ 배열을 ν• λ‹Ήν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€. Frame은 μƒμ„±λœ ν›„ 크기가 λ³€κ²½λ˜λ„λ‘ μ„€κ³„λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— λ°°μ—΄κ³Ό κ°μ²΄λŠ” stack에 μ €μž₯ν•  수 μ—†μŠ΅λ‹ˆλ‹€. ν”„λ ˆμž„μ€ heap의 객체 λ˜λŠ” 배열을 κ°€λ¦¬ν‚€λŠ” 참쑰만 μ €μž₯ν•©λ‹ˆλ‹€. 둜컬 λ³€μˆ˜ λ°°μ—΄(각 frameμ—μ„œ)의 κΈ°λ³Έ λ³€μˆ˜ 및 참쑰와 달리 κ°μ²΄λŠ” 항상 νž™μ— μ €μž₯λ˜λ―€λ‘œ λ©”μ„œλ“œκ°€ μ’…λ£Œλ  λ•Œ μ œκ±°λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λŒ€μ‹  κ°μ²΄λŠ” garbage collector에 μ˜ν•΄μ„œλ§Œ μ œκ±°λ©λ‹ˆλ‹€.

garbage collection을 μ§€μ›ν•˜κΈ° μœ„ν•΄ νž™μ€ μ„Έ λΆ€λΆ„μœΌλ‘œ λ‚˜λ‰©λ‹ˆλ‹€.

  • Young Generation

    • μ’…μ’… Edenκ³Ό Survivor둜 λ‚˜λ‰©λ‹ˆλ‹€.

  • Old Generation

    • Tenured Generation이라고도 함

  • Permanent Generation

Memory Management

객체 및 배열은 garbage collectorκ°€ μžλ™μœΌλ‘œ νšŒμˆ˜ν•˜λŠ” λŒ€μ‹  λͺ…μ‹œμ μœΌλ‘œ ν• λ‹Ή ν•΄μ œλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

일반적으둜 λ‹€μŒκ³Ό 같이 μž‘λ™ν•©λ‹ˆλ‹€.

  1. μƒˆλ‘œμš΄ 객체와 배열이 young generation에 μƒμ„±λ©λ‹ˆλ‹€.

  2. Minor garbage collection은 young generationμ—μ„œ μž‘λ™ν•©λ‹ˆλ‹€. 아직 μ‚΄μ•„μžˆλŠ” κ²μ²΄λŠ” eden κ³΅κ°„μ—μ„œ survivor κ³΅κ°„μœΌλ‘œ μ΄λ™λ©λ‹ˆλ‹€.

  3. 일반적으둜 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ threadλ₯Ό μΌμ‹œ μ€‘μ§€μ‹œν‚€λŠ” Major garbage collection은 μ„ΈλŒ€ 간에 객체λ₯Ό μ΄λ™ν•©λ‹ˆλ‹€. 아직 μ‚΄μ•„μžˆλŠ” κ°μ²΄λŠ” young generationμ—μ„œ old(tenured) generation둜 μ΄λ™λ©λ‹ˆλ‹€.

  4. Permanent generationλŠ” old generationκ°€ μˆ˜μ§‘λ  λ•Œλ§ˆλ‹€ μˆ˜μ§‘λ©λ‹ˆλ‹€. λ‘˜ 쀑 ν•˜λ‚˜κ°€ 가득 μ°¨λ©΄ λ‘˜ λ‹€ μˆ˜μ§‘λ©λ‹ˆλ‹€.

Non-Heap Memory

λ…Όλ¦¬μ μœΌλ‘œ JVM λ©”μ»€λ‹ˆμ¦˜μ˜ μΌλΆ€λ‘œ κ°„μ£Όλ˜λŠ” κ°μ²΄λŠ” Heap에 μƒμ„±λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

non-heap λ©”λͺ¨λ¦¬μ—λŠ” λ‹€μŒμ΄ ν¬ν•¨λ©λ‹ˆλ‹€.

  • Permanent Generation

    • the method area

    • interned strings

  • Code Cache

    • JIT μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ native μ½”λ“œλ‘œ 컴파일된 λ©”μ„œλ“œμ˜ 컴파일 및 μ €μž₯에 μ‚¬μš©

Just In Time (JIT) Compliation

Java λ°”μ΄νŠΈ μ½”λ“œλŠ” ν•΄μ„λ˜μ§€λ§Œ JVM의 호슀트 CPUμ—μ„œ native μ½”λ“œλ₯Ό 직접 μ‹€ν–‰ν•˜λŠ” κ²ƒλ§ŒνΌ λΉ λ₯΄μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€. μ„±λŠ₯을 ν–₯μƒμ‹œν‚€κΈ° μœ„ν•΄ Oracle Hotspot VM은 μ •κΈ°μ μœΌλ‘œ μ‹€ν–‰λ˜λŠ” λ°”μ΄νŠΈ μ½”λ“œμ˜ "ν•«" μ˜μ—­μ„ μ°Ύκ³  이λ₯Ό λ„€μ΄ν‹°λΈŒ μ½”λ“œλ‘œ μ»΄νŒŒμΌν•©λ‹ˆλ‹€. Native codeλŠ” heap이 μ•„λ‹Œ λ©”λͺ¨λ¦¬μ˜ μ½”λ“œ μΊμ‹œμ— μ €μž₯λ©λ‹ˆλ‹€. μ΄λŸ¬ν•œ λ°©μ‹μœΌλ‘œ Hotspot VM은 μ½”λ“œλ₯Ό μ»΄νŒŒμΌν•˜λŠ” 데 κ±Έλ¦¬λŠ” μΆ”κ°€ μ‹œκ°„κ³Ό ν•΄μ„λœ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” 데 κ±Έλ¦¬λŠ” μΆ”κ°€ μ‹œκ°„μ„ μ ˆμΆ©ν•˜λŠ” κ°€μž₯ μ μ ˆν•œ 방법을 μ„ νƒν•˜λ €κ³  ν•©λ‹ˆλ‹€.

Method Area

λ©”μ†Œλ“œ μ˜μ—­μ€ λ‹€μŒκ³Ό 같은 ν΄λž˜μŠ€λ³„ 정보λ₯Ό μ €μž₯ν•©λ‹ˆλ‹€.

  • Classloader Reference

  • Run Time Constant Poll

    • Numertic constants

    • Field references

    • Method References

    • Attributes

  • Field data

    • Per filed

      • Name

      • Type

      • Modifiers

      • Attributes

  • Method data

    • Per method

      • Name

      • Return Type

      • Parameter Types (in order)

      • Modifiers

      • Attributes

  • Method code

    • Per method

      • Bytecodes

      • Operand stack size

      • Local variable size

      • Local variable table

      • Exception table

        • Per exception handler

          • Start point

          • End point

          • PC offset for handler code

          • Constant pool index for exception class being caught

λͺ¨λ“  μŠ€λ ˆλ“œλŠ” λ™μΌν•œ λ©”μ„œλ“œ μ˜μ—­μ„ κ³΅μœ ν•˜λ―€λ‘œ λ©”μ„œλ“œ μ˜μ—­ 데이터에 λŒ€ν•œ μ•‘μ„ΈμŠ€μ™€ 동적 μ—°κ²° ν”„λ‘œμ„ΈμŠ€λŠ” thread safeν•΄μ•Ό ν•©λ‹ˆλ‹€. 두 μŠ€λ ˆλ“œκ°€ 아직 λ‘œλ“œλ˜μ§€ μ•Šμ€ 클래슀의 ν•„λ“œλ‚˜ λ©”μ„œλ“œμ— μ•‘μ„ΈμŠ€ν•˜λ €κ³  μ‹œλ„ν•˜λŠ” 경우 ν•œ 번만 λ‘œλ“œν•΄μ•Ό ν•˜λ©° 두 μŠ€λ ˆλ“œ λͺ¨λ‘ λ‘œλ“œλ  λ•ŒκΉŒμ§€ 싀행을 κ³„μ†ν•΄μ„œλŠ” μ•ˆ λ©λ‹ˆλ‹€.

Class File Structure

컴파일된 클래슀 νŒŒμΌμ€ λ‹€μŒ ꡬ쑰둜 κ΅¬μ„±λ©λ‹ˆλ‹€.

ClassFile {
    u4			magic;
    u2			minor_version;
    u2			major_version;
    u2			constant_pool_count;
    cp_info		contant_pool[constant_pool_count – 1];
    u2			access_flags;
    u2			this_class;
    u2			super_class;
    u2			interfaces_count;
    u2			interfaces[interfaces_count];
    u2			fields_count;
    field_info		fields[fields_count];
    u2			methods_count;
    method_info		methods[methods_count];
    u2			attributes_count;
    attribute_info	attributes[attributes_count];
}
component
description

magic, minor_version, major_version

magic, minor_version, major_version은 클래슀 버전 및 이 ν΄λž˜μŠ€κ°€ 컴파일된 JDK 버전에 λŒ€ν•œ 정보λ₯Ό μ§€μ •ν•©λ‹ˆλ‹€.

constant_pool

Symbol  ν…Œμ΄λΈ”κ³Ό μœ μ‚¬ν•˜μ§€λ§Œ 더 λ§Žμ€ 데이터λ₯Ό ν¬ν•¨ν•˜κ³  μžˆλ‹€ . 이에 λŒ€ν•΄μ„œλŠ” μ•„λž˜μ—μ„œ μžμ„Ένžˆ μ„€λͺ…ν•©λ‹ˆλ‹€.

access_flags

이 ν΄λž˜μŠ€μ— λŒ€ν•œ μˆ˜μ •μž listλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

this_class

이 클래슀의 μ •κ·œν™”λœ 이름(예: org/jamesdbloom/foo/Bar)을 μ œκ³΅ν•˜λŠ” constant_pool에 λŒ€ν•œ 인덱슀

super_class

μƒμœ„ 클래슀 (즉, java/lang/Object)에 λŒ€ν•œ symbolic μ°Έμ‘°λ₯Ό μ œκ³΅ν•˜λŠ” constant_pool에 λŒ€ν•œ 인덱슀

interfaces

κ΅¬ν˜„λœ λͺ¨λ“  μΈν„°νŽ˜μ΄μŠ€μ— λŒ€ν•œ symbolic μ°Έμ‘°λ₯Ό μ œκ³΅ν•˜λŠ” constant_pool에 λŒ€ν•œ 인덱슀 λ°°μ—΄.

fields

각 ν•„λ“œμ— λŒ€ν•œ μ™„μ „ν•œ μ„€λͺ…을 μ œκ³΅ν•˜λŠ” constant_pool에 λŒ€ν•œ 인덱슀 λ°°μ—΄.

methods

각 λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜μ— λŒ€ν•œ μ™„μ „ν•œ μ„€λͺ…을 μ œκ³΅ν•˜λŠ” constant_pool에 λŒ€ν•œ 인덱슀 λ°°μ—΄, λ©”μ„œλ“œκ°€ abstract λ˜λŠ” nativeκ°€ μ•„λ‹Œ 경우 λ°”μ΄νŠΈμ½”λ“œλ„ μ‘΄μž¬ν•©λ‹ˆλ‹€.

attributes

RetentionPolicy.CLASS λ˜λŠ” RetentionPolicy.RUNTIME이 μžˆλŠ” annotaions을 ν¬ν•¨ν•˜μ—¬ ν΄λž˜μŠ€μ— λŒ€ν•œ μΆ”κ°€ 정보λ₯Ό μ œκ³΅ν•˜λŠ” λ‹€μ–‘ν•œ κ°’μ˜ λ°°μ—΄

javap λͺ…령을 μ‚¬μš©ν•˜μ—¬ 컴파일된 Java 클래슀의 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒκ³Ό 같은 κ°„λ‹¨ν•œ 클래슀λ₯Ό μ»΄νŒŒμΌν•˜λŠ” 경우:

package org.jvminternals;

public class SimpleClass {

    public void sayHello() {
        System.out.println("Hello");
    }

}

그런 λ‹€μŒ μ‹€ν–‰ν•˜λ©΄ λ‹€μŒκ³Ό 같은 κ²°κ³Όκ°€ λ‚˜νƒ€λ‚©λ‹ˆλ‹€

javap -v -p -s -sysinfo -constants classes/org/jvminternals/SimpleClass.class
public class org.jvminternals.SimpleClass
  SourceFile: "SimpleClass.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #6.#17         //  java/lang/Object."<init>":()V
   #2 = Fieldref           #18.#19        //  java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #20            //  "Hello"
   #4 = Methodref          #21.#22        //  java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #23            //  org/jvminternals/SimpleClass
   #6 = Class              #24            //  java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lorg/jvminternals/SimpleClass;
  #14 = Utf8               sayHello
  #15 = Utf8               SourceFile
  #16 = Utf8               SimpleClass.java
  #17 = NameAndType        #7:#8          //  "<init>":()V
  #18 = Class              #25            //  java/lang/System
  #19 = NameAndType        #26:#27        //  out:Ljava/io/PrintStream;
  #20 = Utf8               Hello
  #21 = Class              #28            //  java/io/PrintStream
  #22 = NameAndType        #29:#30        //  println:(Ljava/lang/String;)V
  #23 = Utf8               org/jvminternals/SimpleClass
  #24 = Utf8               java/lang/Object
  #25 = Utf8               java/lang/System
  #26 = Utf8               out
  #27 = Utf8               Ljava/io/PrintStream;
  #28 = Utf8               java/io/PrintStream
  #29 = Utf8               println
  #30 = Utf8               (Ljava/lang/String;)V
{
  public org.jvminternals.SimpleClass();
    Signature: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
        0: aload_0
        1: invokespecial #1    // Method java/lang/Object."<init>":()V
        4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
          0      5      0    this   Lorg/jvminternals/SimpleClass;

  public void sayHello();
    Signature: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
        0: getstatic      #2    // Field java/lang/System.out:Ljava/io/PrintStream;
        3: ldc            #3    // String "Hello"
        5: invokevirtual  #4    // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        8: return
      LineNumberTable:
        line 6: 0
        line 7: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
          0      9      0    this   Lorg/jvminternals/SimpleClass;
}

이 클래슀 νŒŒμΌμ€ μƒμˆ˜ ν’€, μƒμ„±μž 및 sayHello λ©”μ„œλ“œμ˜ μ„Έ κ°€μ§€ μ£Όμš” μ„Ήμ…˜μ„ λ³΄μ—¬μ€λ‹ˆλ‹€.

  • Constatn Pool - μ΄λŠ” symbol ν…Œμ΄λΈ”μ΄ 일반적으둜 μ œκ³΅ν•˜λŠ” 것과 λ™μΌν•œ 정보λ₯Ό μ œκ³΅ν•˜λ©° μ•„λž˜μ—μ„œ μžμ„Ένžˆ μ„€λͺ…ν•©λ‹ˆλ‹€

  • Methods – 각각 λ„€ κ°€μ§€ μ˜μ—­ 포함:

    • signature and access flags

    • byte code

    • LineNumberTable - 이것은 디버거에 정보λ₯Ό μ œκ³΅ν•˜μ—¬ μ–΄λ–€ 쀄이 μ–΄λ–€ λ°”μ΄νŠΈ μ½”λ“œ λͺ…령어에 ν•΄λ‹Ήν•˜λŠ”μ§€ ν‘œμ‹œν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ Java μ½”λ“œμ˜ 6번 쀄은 sayHello λ©”μ„œλ“œμ˜ λ°”μ΄νŠΈ μ½”λ“œ 0에 ν•΄λ‹Ήν•˜κ³  7번 쀄은 λ°”μ΄νŠΈ μ½”λ“œ 8에 ν•΄λ‹Ήν•©λ‹ˆλ‹€.

    • LocalVariableTable - 이것은 frame에 제곡된 λͺ¨λ“  μ§€μ—­ λ³€μˆ˜λ₯Ό λ‚˜μ—΄ν•©λ‹ˆλ‹€. 두 μ˜ˆμ œμ—μ„œ μœ μΌν•œ μ§€μ—­ λ³€μˆ˜λŠ” thisμž…λ‹ˆλ‹€.

λ‹€μŒ λ°”μ΄νŠΈ μ½”λ“œ ν”Όμ—°μ‚°μžλŠ” 이 클래슀 νŒŒμΌμ—μ„œ μ‚¬μš©λ©λ‹ˆλ‹€.

aload_0

  • 이 opcodeλŠ” aload_<n>ν˜•μ‹μ˜ opcode κ·Έλ£Ή 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€. 그듀은 λͺ¨λ‘ 객체 μ°Έμ‘°λ₯Ό ν”Όμ—°μ‚°μž μŠ€νƒμ— λ‘œλ“œν•©λ‹ˆλ‹€. <n>은 μ•‘μ„ΈμŠ€λ˜κ³  μžˆμ§€λ§Œ 0, 1, 2 λ˜λŠ” 3만 될 수 μžˆλŠ” 둜컬 λ³€μˆ˜ λ°°μ—΄μ˜ μœ„μΉ˜λ₯Ό β€‹β€‹λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 객체 μ°Έμ‘° iload_<n>μ•„λ‹Œ 값을 λ‘œλ“œν•˜κΈ° μœ„ν•œ λ‹€λ₯Έ μœ μ‚¬ν•œ lload_<n>, float_<n> 및 dload_<n>이 opcodeκ°€ μžˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ„œ iλŠ” int용, l은 long용, fλŠ” float용, dλŠ” doubleμš©μž…λ‹ˆλ‹€. μΈλ±μŠ€κ°€ 3보닀 높은 μ§€μ—­ λ³€μˆ˜λŠ” iload, lload, float, dload 및 aloadλ₯Ό μ‚¬μš©ν•˜μ—¬ λ‘œλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ opcodeλŠ” λͺ¨λ‘ λ‘œλ“œν•  둜컬 λ³€μˆ˜μ˜ 인덱슀λ₯Ό μ§€μ •ν•˜λŠ” 단일 ν”Όμ—°μ‚°μžλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

ldc

  • 이 opcodeλŠ” λŸ°νƒ€μž„ μƒμˆ˜ ν’€μ—μ„œ ν”Όμ—°μ‚°μž μŠ€νƒμœΌλ‘œ μƒμˆ˜λ₯Ό ν‘Έμ‹œν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

getstatic

  • 이 opcodeλŠ” λŸ°νƒ€μž„ μƒμˆ˜ 풀에 λ‚˜μ—΄λœ 정적 ν•„λ“œμ—μ„œ ν”Όμ—°μ‚°μž μŠ€νƒμœΌλ‘œ 정적 값을 ν‘Έμ‹œν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

invokespecial, invokevirtual

  • μ΄λŸ¬ν•œ opcodeλŠ” invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtualκ³Ό 같은 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” opcode 그룹에 μžˆμŠ΅λ‹ˆλ‹€. 이 클래슀 νŒŒμΌμ—μ„œ invokespecial 및 invokevirutal이 λͺ¨λ‘ μ‚¬μš©λ©λ‹ˆλ‹€. 이듀 κ°„μ˜ 차이점은 invokevirutal이 객체의 클래슀λ₯Ό 기반으둜 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. invokespecial λͺ…λ Ήμ–΄λŠ” ν˜„μž¬ 클래슀의 수퍼클래슀의 λ©”μ„œλ“œ 및 μ „μš© λ©”μ„œλ“œλΏλ§Œ μ•„λ‹ˆλΌ μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

return

  • 이 opcodeλŠ” ireturn, lreturn, freturn, dreturn, areturn 및 return opcode 그룹에 μžˆμŠ΅λ‹ˆλ‹€. 각 opcodeλŠ” iκ°€ int, l이 long, fκ°€ float, dκ°€ double, aκ°€ 객체 참쑰인 λ‹€λ₯Έ νƒ€μž…μ„ λ°˜ν™˜ν•˜λŠ” typed return λ¬Έμž…λ‹ˆλ‹€.

일반적인 λ°”μ΄νŠΈ μ½”λ“œμ—μ„œμ™€ 같이 λŒ€λΆ€λΆ„μ˜ ν”Όμ—°μ‚°μžλŠ” λ‹€μŒκ³Ό 같이 둜컬 λ³€μˆ˜, ν”Όμ—°μ‚°μž μŠ€νƒ 및 λŸ°νƒ€μž„ μƒμˆ˜ ν’€κ³Ό μƒν˜Έ μž‘μš©ν•©λ‹ˆλ‹€.

μƒμ„±μžλŠ” 두 개의 λͺ…령을 κ°€μ§€κ³  μžˆλ‹€. λ¨Όμ € this ν”Όμ—°μ‚°μž μŠ€νƒμœΌλ‘œ ν‘Έμ‹œν•˜κ³  λ‹€μŒμœΌλ‘œ 슈퍼 클래슀의 μƒμ„±μžκ°€ ν˜ΈμΆœλ˜μ–΄ thisμ—μ„œ 값을 μ†ŒλΉ„ν•˜λ―€λ‘œ ν”Όμ—°μ‚°μž μŠ€νƒμ—μ„œ κΊΌλƒ…λ‹ˆλ‹€.

sayHello() λ©”μ„œλ“œλŠ” μœ„μ—μ„œ μžμ„Ένžˆ μ„€λͺ…ν•œ κ²ƒμ²˜λŸΌ λŸ°νƒ€μž„ μƒμˆ˜ 풀을 μ‚¬μš©ν•˜μ—¬ μ‹€μ œ 참쑰에 λŒ€ν•œ symbolic μ°Έμ‘°λ₯Ό ν•΄κ²°ν•΄μ•Ό ν•˜λ―€λ‘œ 더 λ³΅μž‘ν•©λ‹ˆλ‹€. 첫 번째 ν”Όμ—°μ‚°μž getstatic은 System 클래슀의 정적 ν•„λ“œ out에 λŒ€ν•œ μ°Έμ‘°λ₯Ό ν”Όμ—°μ‚°μž μŠ€νƒμœΌλ‘œ ν‘Έμ‹œν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€. λ‹€μŒ ν”Όμ—°μ‚°μž ldcλŠ” λ¬Έμžμ—΄ "Hello"λ₯Ό ν”Όμ—°μ‚°μž μŠ€νƒμ— ν‘Έμ‹œν•©λ‹ˆλ‹€. λ§ˆμ§€λ§‰ ν”Όμ—°μ‚°μž invokevirtual은 인수둜 ν”Όμ—°μ‚°μž μŠ€νƒμ—μ„œ "Hello"λ₯Ό κΊΌλ‚΄κ³  ν˜„μž¬ μŠ€λ ˆλ“œμ— λŒ€ν•œ μƒˆ ν”„λ ˆμž„μ„ λ§Œλ“œλŠ” System.out의 println λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.

Faster Class Loading

클래슀 데이터 곡유(CDS)λΌλŠ” κΈ°λŠ₯이 HotSpot JMV 버전 5.0λΆ€ν„° λ„μž…λ˜μ—ˆμŠ΅λ‹ˆλ‹€. JVM μ„€μΉ˜ ν”„λ‘œμ„ΈμŠ€ 쀑에 μ„€μΉ˜ ν”„λ‘œκ·Έλž¨μ€ (rt.jar와 같은) μ£Όμš” JVM 클래슀 집합을 λ©”λͺ¨λ¦¬ λ§€ν•‘λœ 곡유 μ•„μΉ΄μ΄λΈŒλ‘œ λ‘œλ“œν•©λ‹ˆλ‹€. CDSλŠ” μ΄λŸ¬ν•œ 클래슀λ₯Ό λ‘œλ“œν•˜λŠ” 데 κ±Έλ¦¬λŠ” μ‹œκ°„μ„ 쀄여 JVM μ‹œμž‘ 속도λ₯Ό κ°œμ„ ν•˜κ³  μ΄λŸ¬ν•œ 클래슀λ₯Ό JVM의 μ„œλ‘œ λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€ 간에 κ³΅μœ ν•  수 μžˆλ„λ‘ ν•˜μ—¬ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ„ μ€„μž…λ‹ˆλ‹€.

Where Is The Method Area

JVM(Java Virtual Machine) 사양 Java SE 7 Editionμ—λŠ” "λ©”μ„œλ“œ μ˜μ—­μ΄ λ…Όλ¦¬μ μœΌλ‘œ heap의 μΌλΆ€μ΄μ§€λ§Œ κ°„λ‹¨ν•œ κ΅¬ν˜„μ—μ„œλŠ” garbage collect λ˜λŠ” 압좕을 μ„ νƒν•˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. ". Oracle JVM용 jconsoleκ³Ό 달리 λ©”μ„œλ“œ μ˜μ—­(및 μ½”λ“œ μΊμ‹œ)이 non-heap μ•„λ‹Œ κ²ƒμœΌλ‘œ ν‘œμ‹œλ©λ‹ˆλ‹€. OpenJDK μ½”λ“œλŠ” CodeCacheκ°€ ObjectHeap에 λŒ€ν•œ VM의 λ³„λ„μ˜ ν•„λ“œμž„μ„ λ³΄μ—¬μ€λ‹ˆλ‹€.

Classloader Reference

λ‘œλ“œλ˜λŠ” λͺ¨λ“  ν΄λž˜μŠ€μ—λŠ” 이λ₯Ό λ‘œλ“œν•œ 클래슀 λ‘œλ”μ— λŒ€ν•œ μ°Έμ‘°κ°€ ν¬ν•¨λ©λ‹ˆλ‹€. 그리고 클래슀 λ‘œλ”μ—λŠ” λ‘œλ“œν•œ λͺ¨λ“  ν΄λž˜μŠ€μ— λŒ€ν•œ 참쑰도 ν¬ν•¨λ©λ‹ˆλ‹€.

Run Time Constant Pool

JVM은 더 λ§Žμ€ 데이터λ₯Ό ν¬ν•¨ν•˜μ§€λ§Œ symbol ν…Œμ΄λΈ”κ³Ό μœ μ‚¬ν•œ λŸ°νƒ€μž„ 데이터 ꡬ쑰인 νƒ€μž…λ³„ μƒμˆ˜ 풀을 μœ μ§€ν•©λ‹ˆλ‹€. Java의 λ°”μ΄νŠΈ μ½”λ“œμ—λŠ” 데이터가 ν•„μš”ν•˜λ©°, μ’…μ’… 이 λ°μ΄ν„°λŠ” λ°”μ΄νŠΈ μ½”λ“œμ— 직접 μ €μž₯ν•˜κΈ°μ—λŠ” λ„ˆλ¬΄ ν½λ‹ˆλ‹€. λŒ€μ‹  μƒμˆ˜ 풀에 μ €μž₯되고 λ°”μ΄νŠΈ μ½”λ“œμ—λŠ” μƒμˆ˜ 풀에 λŒ€ν•œ μ°Έμ‘°κ°€ ν¬ν•¨λ©λ‹ˆλ‹€. λŸ°νƒ€μž„ μƒμˆ˜ 풀은 μœ„μ—μ„œ μ„€λͺ…ν•œ λŒ€λ‘œ 동적 연결에 μ‚¬μš©λ©λ‹ˆλ‹€.

λ‹€μŒμ„ ν¬ν•¨ν•˜μ—¬ μ—¬λŸ¬ νƒ€μž…μ˜ 데이터가 μƒμˆ˜ 풀에 μ €μž₯λ©λ‹ˆλ‹€.

  • numeric literals

  • string literals

  • class references

  • field references

  • method references

예λ₯Ό λ“€μ–΄ λ‹€μŒ μ½”λ“œ:

Object foo = new Object();

λ‹€μŒκ³Ό 같이 λ°”μ΄νŠΈ μ½”λ“œλ‘œ μž‘μ„±λ©λ‹ˆλ‹€.

 0: 	new #2 		    // Class java/lang/Object
 1:	dup
 2:	invokespecial #3    // Method java/ lang/Object "<init>"( ) V

new opcode(ν”Όμ—°μ‚°μž μ½”λ“œ) λ‹€μŒμ—λŠ” #2 ν”Όμ—°μ‚°μžκ°€ μ˜΅λ‹ˆλ‹€. 이 ν”Όμ—°μ‚°μžλŠ” μƒμˆ˜ 풀에 λŒ€ν•œ μΈλ±μŠ€μ΄λ―€λ‘œ μƒμˆ˜ ν’€μ˜ 두 번째 ν•­λͺ©μ„ μ°Έμ‘°ν•©λ‹ˆλ‹€. 두 번째 ν•­λͺ©μ€ 클래슀 참쑰이며, 이 ν•­λͺ©μ€ 값이 // Class java/lang/Object인 μƒμˆ˜ UTF8 string둜 클래슀 이름을 ν¬ν•¨ν•˜λŠ” μƒμˆ˜ ν’€μ˜ λ‹€λ₯Έ ν•­λͺ©μ„ μ°¨λ‘€λ‘œ μ°Έμ‘°ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ 이 symbolic 링크λ₯Ό μ‚¬μš©ν•˜μ—¬ java.lang.Object에 λŒ€ν•œ 클래슀λ₯Ό μ‘°νšŒν•  수 μžˆμŠ΅λ‹ˆλ‹€. new opcodeλŠ” 클래슀 μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€κ³  ν•΄λ‹Ή λ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ μƒˆ 클래슀 μΈμŠ€ν„΄μŠ€μ— λŒ€ν•œ μ°Έμ‘°κ°€ ν”Όμ—°μ‚°μž μŠ€νƒμ— μΆ”κ°€λ©λ‹ˆλ‹€. 그런 λ‹€μŒ dup opcodeλŠ” ν”Όμ—°μ‚°μž μŠ€νƒμ—μ„œ μƒμœ„ 참쑰의 μΆ”κ°€ 볡사본을 μƒμ„±ν•˜κ³  이λ₯Ό ν”Όμ—°μ‚°μž μŠ€νƒμ˜ μ΅œμƒμœ„μ— μΆ”κ°€ν•©λ‹ˆλ‹€. λ§ˆμ§€λ§‰μœΌλ‘œ μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ†Œλ“œλŠ” invokespecial에 μ˜ν•΄ 2ν–‰μ—μ„œ ν˜ΈμΆœλ©λ‹ˆλ‹€. 이 ν”Όμ—°μ‚°μžλŠ” μƒμˆ˜ 풀에 λŒ€ν•œ 참쑰도 ν¬ν•¨ν•©λ‹ˆλ‹€. μ΄ˆκΈ°ν™” λ©”μ„œλ“œλŠ” λ©”μ„œλ“œμ— λŒ€ν•œ 인수둜 ν”Όμ—°μ‚°μž ν’€μ—μ„œ μ΅œμƒμœ„ μ°Έμ‘°λ₯Ό μ†ŒλΉ„(팝)ν•©λ‹ˆλ‹€. λ§ˆμ§€λ§‰μ—λŠ” μƒμ„±λ˜κ³  μ΄ˆκΈ°ν™”λœ μƒˆ 객체에 λŒ€ν•œ ν•˜λ‚˜μ˜ μ°Έμ‘°κ°€ μžˆμŠ΅λ‹ˆλ‹€.

λ‹€μŒκ³Ό 같은 κ°„λ‹¨ν•œ 클래슀λ₯Ό μ»΄νŒŒμΌν•˜λŠ” 경우:

package org.jvminternals;

public class SimpleClass {

    public void sayHello() {
        System.out.println("Hello");
    }

}

μƒμ„±λœ 클래슀 파일의 μƒμˆ˜ 풀은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

Constant pool:
   #1 = Methodref          #6.#17         //  java/lang/Object."<init>":()V
   #2 = Fieldref           #18.#19        //  java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #20            //  "Hello"
   #4 = Methodref          #21.#22        //  java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #23            //  org/jvminternals/SimpleClass
   #6 = Class              #24            //  java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lorg/jvminternals/SimpleClass;
  #14 = Utf8               sayHello
  #15 = Utf8               SourceFile
  #16 = Utf8               SimpleClass.java
  #17 = NameAndType        #7:#8          //  "<init>":()V
  #18 = Class              #25            //  java/lang/System
  #19 = NameAndType        #26:#27        //  out:Ljava/io/PrintStream;
  #20 = Utf8               Hello
  #21 = Class              #28            //  java/io/PrintStream
  #22 = NameAndType        #29:#30        //  println:(Ljava/lang/String;)V
  #23 = Utf8               org/jvminternals/SimpleClass
  #24 = Utf8               java/lang/Object
  #25 = Utf8               java/lang/System
  #26 = Utf8               out
  #27 = Utf8               Ljava/io/PrintStream;
  #28 = Utf8               java/io/PrintStream
  #29 = Utf8               println
  #30 = Utf8               (Ljava/lang/String;)V

μƒμˆ˜ ν’€μ—λŠ” λ‹€μŒ μœ ν˜•μ΄ ν¬ν•¨λ©λ‹ˆλ‹€

Types
Description

Integer

4λ°”μ΄νŠΈ int μƒμˆ˜

Long

8λ°”μ΄νŠΈ long μƒμˆ˜

Float

4λ°”μ΄νŠΈ float μƒμˆ˜

Double

8λ°”μ΄νŠΈ double μƒμˆ˜

String

μ‹€μ œ λ°”μ΄νŠΈλ₯Ό ν¬ν•¨ν•˜λŠ” μƒμˆ˜ ν’€μ˜ λ‹€λ₯Έ Utf8 ν•­λͺ©μ„ κ°€λ¦¬ν‚€λŠ” λ¬Έμžμ—΄ μƒμˆ˜

Utf8

Utf8둜 μΈμ½”λ”©λœ 문자 μ‹œν€€μŠ€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ°”μ΄νŠΈ 슀트림

Class

λ‚΄λΆ€ JVM ν˜•μ‹μ˜ μ •κ·œν™”λœ 클래슀 이름을 ν¬ν•¨ν•˜λŠ” μƒμˆ˜ ν’€μ˜ λ‹€λ₯Έ Utf8 ν•­λͺ©μ„ κ°€λ¦¬ν‚€λŠ” 클래슀 μƒμˆ˜(동적 μ—°κ²° ν”„λ‘œμ„ΈμŠ€μ—μ„œ μ‚¬μš©λ¨)

NameAndType

μƒμˆ˜ ν’€μ˜ λ‹€λ₯Έ ν•­λͺ©μ„ 각각 κ°€λ¦¬ν‚€λŠ” 콜둠으둜 κ΅¬λΆ„λœ κ°’ μŒμž…λ‹ˆλ‹€. 첫 번째 κ°’(콜둠 μ•ž)은 λ©”μ„œλ“œ λ˜λŠ” ν•„λ“œ 이름인 Utf8 λ¬Έμžμ—΄ ν•­λͺ©μ„ κ°€λ¦¬ν‚΅λ‹ˆλ‹€. 두 번째 값은 μœ ν˜•μ„ λ‚˜νƒ€λ‚΄λŠ” Utf8 ν•­λͺ©μ„ κ°€λ¦¬ν‚΅λ‹ˆλ‹€. ν•„λ“œμ˜ 경우 μ •κ·œν™”λœ 클래슀 이름이고 λ©”μ„œλ“œμ˜ 경우 λ§€κ°œλ³€μˆ˜λ‹Ή ν•˜λ‚˜μ˜ μ •κ·œν™”λœ 클래슀 이름 listμž…λ‹ˆλ‹€.

Fielddref, Methodref, InterfaceMethodref

μƒμˆ˜ ν’€μ˜ λ‹€λ₯Έ ν•­λͺ©μ„ 각각 κ°€λ¦¬ν‚€λŠ” 점으둜 κ΅¬λΆ„λœ κ°’ μŒμž…λ‹ˆλ‹€. 첫 번째 κ°’(점 μ•ž)은 클래슀 ν•­λͺ©μ„ κ°€λ¦¬ν‚΅λ‹ˆλ‹€. 두 번째 값은 NameAndType ν•­λͺ©μ„ κ°€λ¦¬ν‚΅λ‹ˆλ‹€.

Exception Table

μ˜ˆμ™Έ ν…Œμ΄λΈ”μ€ λ‹€μŒκ³Ό 같은 μ˜ˆμ™Έλ³„ ν•Έλ“€λŸ¬ 정보λ₯Ό μ €μž₯ν•©λ‹ˆλ‹€.

  • μ‹œμž‘μ 

  • 쒅점

  • ν•΄λ“€λŸ¬ μ½”λ“œμ˜ PC offset

  • catchλ˜λŠ” μ˜ˆμ™Έ ν΄λž˜μŠ€μ— λŒ€ν•œ μƒμˆ˜ ν’€ 인덱슀

λ©”μ„œλ“œκ°€ try-catch λ˜λŠ” try-finally μ˜ˆμ™Έ 처리기λ₯Ό μ •μ˜ν•œ 경우 μ˜ˆμ™Έ ν…Œμ΄λΈ”μ΄ μƒμ„±λ©λ‹ˆλ‹€. μ—¬κΈ°μ—λŠ” ν•Έλ“€λŸ¬κ°€ μ μš©λ˜λŠ” λ²”μœ„, μ²˜λ¦¬λ˜λŠ” μ˜ˆμ™Έ μœ ν˜• 및 ν•Έλ“€λŸ¬ μ½”λ“œκ°€ μžˆλŠ” μœ„μΉ˜λ₯Ό ν¬ν•¨ν•˜μ—¬ 각 μ˜ˆμ™Έ ν•Έλ“€λŸ¬ λ˜λŠ” finally 블둝에 λŒ€ν•œ 정보가 ν¬ν•¨λ©λ‹ˆλ‹€.

μ˜ˆμ™Έκ°€ λ°œμƒν•˜λ©΄ JVM은 ν˜„μž¬ λ©”μ„œλ“œμ—μ„œ μΌμΉ˜ν•˜λŠ” ν•Έλ“€λŸ¬λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€. 아무것도 μ—†μœΌλ©΄ λ©”μ„œλ“œλŠ” ν˜„μž¬ μŠ€νƒ ν”„λ ˆμž„μ„ κ°‘μžκΈ° νŒν•˜μ—¬ μ’…λ£Œν•˜κ³  μ˜ˆμ™ΈλŠ” 호좜 λ©”μ„œλ“œ(μƒˆ ν˜„μž¬ ν”„λ ˆμž„)μ—μ„œ λ‹€μ‹œ throwλ©λ‹ˆλ‹€. λͺ¨λ“  ν”„λ ˆμž„μ΄ 팝되기 전에 μ˜ˆμ™Έ μ²˜λ¦¬κΈ°κ°€ λ°œκ²¬λ˜μ§€ μ•ŠμœΌλ©΄ μŠ€λ ˆλ“œκ°€ μ’…λ£Œλ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ μŠ€λ ˆλ“œκ°€ κΈ°λ³Έ μŠ€λ ˆλ“œμΈ κ²½μš°μ™€ 같이 데λͺ¬μ΄ μ•„λ‹Œ λ§ˆμ§€λ§‰ μŠ€λ ˆλ“œμ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•˜λ©΄ JVM μžμ²΄κ°€ μ’…λ£Œλ  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ μ˜ˆμ™Έ ν•Έλ“€λŸ¬λŠ” λͺ¨λ“  μœ ν˜•μ˜ μ˜ˆμ™Έμ™€ μΌμΉ˜ν•˜λ―€λ‘œ μ˜ˆμ™Έκ°€ λ°œμƒν•  λ•Œλ§ˆλ‹€ 항상 μ‹€ν–‰λ©λ‹ˆλ‹€. μ˜ˆμ™Έκ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ” 경우 λ©”μ„œλ“œ λμ—μ„œ finally 블둝이 μ—¬μ „νžˆ μ‹€ν–‰λ˜λ©°, μ΄λŠ” return 문이 μ‹€ν–‰λ˜κΈ° 직전에 finally ν•Έλ“€λŸ¬ μ½”λ“œλ‘œ μ ν”„ν•˜μ—¬ λ‹¬μ„±λ©λ‹ˆλ‹€.

Symbol Table

μœ ν˜•λ³„ λŸ°νƒ€μž„ μƒμˆ˜ ν’€ 외에도 Hotspot JVMμ—λŠ” permanent generation에 λ³΄κ΄€λœ symbol ν…Œμ΄λΈ”μ΄ μžˆμŠ΅λ‹ˆλ‹€. symbol ν…Œμ΄λΈ”μ€ symbol에 λŒ€ν•œ ν•΄μ‹œ ν…Œμ΄λΈ” λ§€ν•‘ symbol 포인터(즉, Hashtable<Symbol*, Symbol>)이며 각 클래슀의 λŸ°νƒ€μž„ μƒμˆ˜ 풀에 μžˆλŠ” symbolλ₯Ό ν¬ν•¨ν•˜μ—¬ λͺ¨λ“  symbol에 λŒ€ν•œ 포인터λ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€.

Reference counting은 symbol ν…Œμ΄λΈ”μ—μ„œ symbolκ°€ μ œκ±°λ˜λŠ” μ‹œκΈ°λ₯Ό μ œμ–΄ν•˜λŠ” ​​데 μ‚¬μš©λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ ν΄λž˜μŠ€κ°€ μ–Έλ‘œλ“œλ˜λ©΄ λŸ°νƒ€μž„ μƒμˆ˜ 풀에 λ³΄κ΄€λœ λͺ¨λ“  symbol의 μ°Έμ‘° νšŸμˆ˜κ°€ κ°μ†Œν•©λ‹ˆλ‹€. symbol ν…Œμ΄λΈ”μ— μžˆλŠ” symbol의 μ°Έμ‘° νšŸμˆ˜κ°€ 0이 되면 symbol ν…Œμ΄λΈ”μ€ symbol이 더 이상 μ°Έμ‘°λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것을 μ•Œκ³  ν•΄λ‹Ή symbol이 symbol ν…Œμ΄λΈ”μ—μ„œ μ–Έλ‘œλ“œλ©λ‹ˆλ‹€. symbol ν…Œμ΄λΈ”κ³Ό λ¬Έμžμ—΄ ν…Œμ΄λΈ”(μ•„λž˜ μ°Έμ‘°) λͺ¨λ‘μ— λŒ€ν•΄ νš¨μœ¨μ„±μ„ 높이고 각 ν•­λͺ©μ΄ ν•œ 번만 ν‘œμ‹œλ˜λ„λ‘ ν•˜κΈ° μœ„ν•΄ λͺ¨λ“  ν•­λͺ©μ΄ ν‘œμ€€ν™”λœ ν˜•μ‹μœΌλ‘œ μœ μ§€λ©λ‹ˆλ‹€.

Interned Strings (String Table)

Java μ–Έμ–΄ μ‚¬μ–‘μ—μ„œλŠ” λ™μΌν•œ μ‹œν€€μŠ€μ˜ μœ λ‹ˆμ½”λ“œ μ½”λ“œ 포인트λ₯Ό ν¬ν•¨ν•˜λŠ” λ™μΌν•œ λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄μ΄ λ™μΌν•œ String μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•΄μ•Ό ν•œλ‹€κ³  μš”κ΅¬ν•©λ‹ˆλ‹€. λ˜ν•œ String.intern()이 String의 μΈμŠ€ν„΄μŠ€μ—μ„œ 호좜되면 string이 λ¦¬ν„°λŸ΄μΈ 경우 μ°Έμ‘° λ°˜ν™˜κ³Ό λ™μΌν•œ μ°Έμ‘°κ°€ λ°˜ν™˜λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. λ”°λΌμ„œ λ‹€μŒμ΄ trueμž…λ‹ˆλ‹€.

("j" + "v" + "m").intern() == "jvm"

Hotspot JVMμ—μ„œ interned string은 symbols(예: Hashtable<oop, Symbol>)에 λŒ€ν•œ Hashtable λ§€ν•‘ 객체 포인터인 string ν…Œμ΄λΈ”μ— λ³΄κ΄€λ˜λ©° permanent generation에 λ³΄κ΄€λ©λ‹ˆλ‹€. symbol ν…Œμ΄λΈ”(μœ„ μ°Έμ‘°)κ³Ό string ν…Œμ΄λΈ” λͺ¨λ‘μ— λŒ€ν•΄ νš¨μœ¨μ„±μ„ 높이고 각 ν•­λͺ©μ΄ ν•œ 번만 ν‘œμ‹œλ˜λ„λ‘ ν•˜κΈ° μœ„ν•΄ λͺ¨λ“  ν•­λͺ©μ΄ ν‘œμ€€ν™”λœ ν˜•μ‹μœΌλ‘œ μœ μ§€λ©λ‹ˆλ‹€.

String λ¦¬ν„°λŸ΄μ€ μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ μžλ™μœΌλ‘œ interned되고 ν΄λž˜μŠ€κ°€ λ‘œλ“œλ  λ•Œ symbol ν…Œμ΄λΈ”μ— μΆ”κ°€λ©λ‹ˆλ‹€. λ˜ν•œ String 클래슀의 μΈμŠ€ν„΄μŠ€λŠ” String.intern()을 ν˜ΈμΆœν•˜μ—¬ λͺ…μ‹œμ μœΌλ‘œ internedν•  수 μžˆμŠ΅λ‹ˆλ‹€. String.intern()이 호좜될 λ•Œ symbol ν…Œμ΄λΈ”μ— 이미 λ¬Έμžμ—΄μ΄ ν¬ν•¨λ˜μ–΄ 있으면 this에 λŒ€ν•œ μ°Έμ‘°κ°€ λ°˜ν™˜λ˜κ³  κ·Έλ ‡μ§€ μ•Šμ€ 경우 string이 string ν…Œμ΄λΈ”μ— μΆ”κ°€λ˜κ³  ν•΄λ‹Ή μ°Έμ‘°κ°€ λ°˜ν™˜λ©λ‹ˆλ‹€

Last updated 2 years ago

Was this helpful?

JVM은 λΆ€νŠΈμŠ€νŠΈλž© ν΄λž˜μŠ€λ‘œλ”λ₯Ό μ‚¬μš©ν•˜μ—¬ 초기 클래슀λ₯Ό λ‘œλ“œν•˜μ—¬ μ‹œμž‘λ©λ‹ˆλ‹€. 그런 λ‹€μŒ public static void main(String[])이 호좜되기 전에 ν΄λž˜μŠ€κ°€ μ—°κ²°λ˜κ³  μ΄ˆκΈ°ν™”λ©λ‹ˆλ‹€. 이 λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ ν•„μš”μ— 따라 μΆ”κ°€ 클래슀 및 μΈν„°νŽ˜μ΄μŠ€μ˜ , 및 κ°€ μ°¨λ‘€λ‘œ μ‹€ν–‰λ©λ‹ˆλ‹€.

Classloader
λ‘œλ“œ
μ—°κ²°
μ΄ˆκΈ°ν™”