-
JVM 및 메모리 관리
-
자바의 동작 원리에 대해 설명해 보세요.
-
JVM에 대해 설명해 보세요.
-
자바 바이트 코드는 어떤 역할을 하는지 설명해 보세요.
-
JDK와 JRE의 차이점에 대해 설명해 보세요.
-
클래스 로더는 무엇이며 어떤 역할을 하는지 설명해 보세요.
-
JIT 컴파일러는 무엇인지 설명해 보세요.
-
JVM 메모리 영역(Heap, Stack 등)에 대해 설명해 보세요.
-
가비지 컬렉션에 대해 설명해 보세요.
-
가비지 컬렉터에 대해 설명해 보세요.
-
Full GC에 대해서도 설명해 보세요
-
가비지 컬렉션의 동작과정에서 Stop-The-World란 무엇인가요?
-
메모리 관리 및 직렬화
-
직렬화와 역직렬화에 대해 설명해 보세요.
-
SerialVersionUID를 선언해야 하는 이유에 대해 설명해 보세요.
개인적으로 기술면접을 준비하면서 작성한 글입니다.
잘못된 내용이 기재되어 있으면 댓글로 말씀해 주시면 감사하겠습니다.. :)
지속적으로 확인하여 퀄리티 향상을 위해 힘써보겠습니다..
JVM 및 메모리 관리
자바의 동작 원리에 대해 설명해 보세요.
개발자는 [.java] 확장자 파일에 자바 소스 코드를 작성합니다. 이 파일은 자바 프로그램의 원시 코드를 포함합니다. 그리고 자바 컴파일러가 [.java] 파일의 소스 코드를 바이트 코드로 변환하며, [.class] 확장자 파일로 저장됩니다. 이 파일은 플랫폼 독립적인 중간 표현 형태입니다.
[.class] 파일들은 JVM 시작 또는 런타임 중에 필요할 때 클래스 로더에 의해 메모리에 로드됩니다. 이 과정은 필요한 클래스를 동적으로 로드하여 메모리에 배치합니다.그리고 JVM 내에 내장된 자바 인터프리터 또는 JIT 컴파일러는 [.class] 파일의 바이트 코드를 해석하거나 기계 코드로 컴파일합니다. 이 기계어 코드는 운영체제 위에서 직접 실행됩니다.JVM 내부에서 변환된 기계어는 OS 위에서 직접 실행됩니다. 이로 인해, JVM이 설치되어 있는 모든 플랫폼에서 동일한 바이트 코드가 동일하게 실행될 수 있습니다.
JVM에 대해 설명해 보세요.
JVM은 자바 바이트 코드 [. class] 파일을 실행하기 위한 가상 머신입니다.
JVM은 자바 프로그램의 플랫폼 독립성을 보장하는 핵심 요소입니다.
- 플랫폼 독립성
- JVM의 가장 중요한 특징은 플랫폼 독립성입니다.
- 바이트 코드가 특정 하드웨어나 운영체제에 종속되지 않기 때문에, Java 코드는 한 번 작성하면 어디에서나 실행될 수 있습니다.
- 대신 JVM은 해당 바이트 코드를 현지 시스템에 맞게 해석하고 실행합니다.
- 메모리 관리
- JVM 내부에는 가비지 컬렉터가 포함되어 있어, 더 이상 사용되지 않는 객체를 자동으로 회수하는 메모리 관리를 자동화하는 역할도 수행합니다.
- JVM의 아키텍처 및 주요 구성 요소
- Class Loader
- 바이트 코드를 로드하고 검증하는 역할을 합니다.
- Runtime Data Area
- JVM이 프로그램을 실행하는 동안 사용하는 메모리 영역입니다.
- 여기에는 메서드 영역, 힙 영역, 스택 영역, PC 레지스터, 그리고 네이티브 메서드 스택이 포함됩니다.
- Execution Engine
- 바이트 코드를 실행하는 역할을 합니다. Just-In-Time 컴파일러와 인터프리터가 여기에 포함됩니다.
- Native Interface
- JVM 내부의 Execution Engine과 외부의 Native Libraries를 연결합니다.
- Native Libraries
- 자바 API의 기본 구현을 제공하는 플랫폼 특정 라이브러리입니다.
- Class Loader
- 보안
- JVM은 플랫폼의 보안을 위해 몇 가지 중요한 메커니즘을 제공합니다.
- 예를 들면, 클래스 로더의 검증 기능을 통해 바이트 코드의 유효성을 검사하거나, 스택 검사를 통해 애플리케이션의 코드와 라이브러리 코드 사이의 상호 작용을 확인합니다.
자바 바이트 코드는 어떤 역할을 하는지 설명해 보세요.
자바 바이트 코드는 자바 소스 코드 [. java] 파일이 자바 컴파일러에 의해 컴파일되어 생성되는 중간 코드 [. class] 파일입니다. 자바의 플랫폼 독립성과 이식성을 보장하는 핵심 요소이며, 다양한 환경에서 동일한 프로그램 동작을 보장하는 역할을 합니다.
JDK와 JRE의 차이점에 대해 설명해 보세요.
JDK와 JRE는 Java 프로그램 개발과 실행에 필요한 도구들을 제공합니다.
- JDK(Java Development Kit)
- JDK는 개발자가 Java 프로그램을 개발하기 위해 필요한 도구 모음입니다.
- javac와 같은 도구를 포함하여, 자바 소스 코드 [. java] 파일을 바이트 코드 [. class] 파일로 컴파일하는 데 필요한 컴파일러도 포함됩니다.
- 또한, 개발 중에 필요한 다양한 유틸리티도 함께 제공됩니다.
- JDK 내부에는 JRE도 포함되어 있으므로, JDK를 설치하면 JRE도 함께 설치됩니다.
- JRE(Java Runtime Environment)
- JRE는 컴파일된 Java 프로그램을 실행하기 위해 필요한 환경을 제공합니다.
- 중요한 구성 요소로 JVM이 있으며, 바이트 코드를 현지 플랫폼의 기계 코드로 변환하고 실행합니다.
- JRE만 설치되어 있다면 Java 프로그램을 실행할 수 있지만 개발은 할 수 없습니다.
- 또한, Java API와 같은 기본 클래스 라이브러리도 포함됩니다.
클래스 로더는 무엇이며 어떤 역할을 하는지 설명해 보세요.
클래스 로더는 JVM 내에서 클래스 파일들을 로드하기 위한 역할을 수행합니다.
- 클래스 로더의 계층구조
- Java의 클래스 로더는 계층적으로 동작합니다.
- 이 계층구조 내에서, 여러 클래스들이 동작하며 대표적으로 Bootstrap ClassLoader, Extension ClassLoader 그리고 Application ClassLoader가 있습니다.
- Bootstrap ClassLoader는 JDK 내부의 핵심 자바 API들을 로드합니다.
- Extension ClassLoader는 확장 디렉토리의 클래스들을 로드합니다.
- Application ClassLoader는 환경 변수나 -cp, -classpath 옵션으로 지정된 경로의 클래스들을 로드합니다.
- 동적 로딩
- 클래스 로더의 능력 중 하나는 클래스를 동적으로 로드하는 것입니다.
- 이것은 자바가 런타임에 필요한 클래스를 로드할 수 있게 하므로, 모든 클래스가 애플리케이션 시작 시에 로드될 필요가 없습니다.
- 사용자 정의 클래스 로더
- 필요에 따라 개발자는 java.lang.ClassLoader 클래스를 상속받아 사용자 정의 클래스 로더를 구현할 수 있습니다.
- 이를 통해 특정 로직 또는 규칙에 따라 클래스를 로드할 수 있습니다.
즉, 클래스 로더는 자바 바이트 코드를 JVM에 동적으로 로드하며, 이를 위한 계층적 구조와 메커니즘을 제공합니다. 클래스 로딩 과정에서 로딩, 연결 그리고 초기화 단계를 거치며, 이를 통해 자바 프로그램의 유연성과 동적성이 보장됩니다.
JIT 컴파일러는 무엇인지 설명해 보세요.
JIT 컴파일러는 프로그램의 실행 시점에 바이트 코드나 중간 코드를 해당 시스템의 기계어로 컴파일하는 기술입니다.
- 장점
- 성능 향상 : 바이트 코드를 직접 해석하는 것보다, JIT 컴파일러에 의해 기계어로 변환된 코드는 훨씬 빠르게 실행됩니다.
- 런타임 최적화 : JIT 컴파일러는 프로그램이 실행되는 동안 수집한 정보를 바탕으로 더 효율적인 최적화를 수행합니다.
- 단점
- 초기 오버헤드 : 프로그램 시작 시 JIT 컴파일러는 바이트 코드를 기계어로 컴파일하는 과정에 시간을 소요하므로, 초기에 느릴 수 있습니다.
- 메모리 사용량 : JIT 컴파일 과정은 추가적인 메모리를 사용합니다.
JVM 메모리 영역(Heap, Stack 등)에 대해 설명해 보세요.
자바의 JVM위에서 실행되며, JVM은 메모리를 여러 영역으로 관리합니다.
주요 영역으로는 힙, 스택, 메서드 영역, PC 레지스터, 네이티브 메서드 스택 등이 있습니다.
- 힙(Heap)
- 힙은 객체의 인스턴스가 할당되는 영역입니다. 즉, new 키워드로 생성된 객체는 모두 이곳에 생성됩니다.
- 객체의 동적 데이터가 저장되는 영역으로, 대부분의 객체와 배열이 여기에 할당됩니다.
- 가비지 컬렉터가 활동하는 주요 영역이기도 하며, 사용되지 않는 객체는 이 영역에서 정리됩니다.
- 스택(Stack)
- 스택은 스레드별로 하나씩 존재하며, 메서드의 호출 정보, 지역 변수, 매개 변수 등이 저장되는 영역입니다.
- 각 메서드 호출에 따른 로컬 변수, 임시 데이터, 매개 변수, 변환 주소 등이 스택 프레임 형태로 쌓입니다.
- 메서드 호출이 종료되면, 해당 메서드에 대한 스택 프레임은 스택에서 제거됩니다.
- LIFO 구조를 갖고 변수에 새로운 데이터가 할당되면 이전 데이터는 사라집니다.
- 메서드 영역(Method Area)
- 클래스 파일의 바이트 코드, 변수 이름, 메서드 이름, 상수 풀 같은 메타 데이터와 정적 변수 등 클래스 수준의 정보가 저장됩니다.
- JVM 시작 시 생성되고 종료될 때까지 유지됩니다.
- PC 레지스터
- 현재 실행 중인 JVM 명령의 주소를 가집니다. 이 영역은 스레드마다 하나씩 생성됩니다.
- 네이티브 메서드 스택
- 자바 외의 언어로 작성된 네이티브 코드를 위한 메모리 영역입니다.
가비지 컬렉션에 대해 설명해 보세요.
가비지 컬렉션은 프로그램 실행 중에 동적으로 할당된 메모리 중 사용되지 않는 부분을 자동으로 회수하는 메모리 관리 기법입니다.
이로써 프로그래머는 직접 메모리를 해제하는 작업을 하지 않아도 되며, 이는 메모리 누수나 관련된 오류를 방지하는 데 큰 도움이 됩니다.
가비지 컬렉터에 대해 설명해 보세요.
가비지 컬렉터는 가비지 컬렉션 프로세스를 수행하는 JVM의 일부로, 자동 메모리 관리 시스템입니다.
가비지 컬렉터의 주 역할은 힙 메모리 영역에서 더 이상 사용되지 않는 객체를 식별하고, 그 객체들이 차지하고 있는 메모리를 해제하여 재사용 가능하게 만드는 것입니다.
- 작동 원리
- 참조 추적 : 가비지 컬렉터는 실행 중인 프로그램에서 더 이상 참조되지 않는 객체를 식별합니다.
- 메모리 회수 : 식별된 더 이상 사용되지 않는 객체의 메모리를 해제합니다.
- Stop-The-World
- 가비지 컬렉션 동작 시에는 JVM이 애플리케이션의 실행을 일시적으로 멈추는데, 이를 Stop-The-World라고 합니다.
- 이 시간 동안 애플리케이션의 모든 스레드가 일시 중지됩니다.
- 메모리 구조와 가비지 컬렉션
- Java의 힙 메모리는 크게 Young Generation과 Old Generation으로 나눠집니다.
- 대부분의 객체는 Young 영역에 생성되고, 일정 시간 이상 살아남은 객체는 Old 영역으로 이동됩니다.
- 가비지 컬렉터는 이 두 영역에 따라 다르게 동작합니다.
- 주요 가비지 컬렉터
- Java에서는 여러 가비지 컬렉터를 제공합니다.
- 주요한 것들로는 Parallel GC, G1 GC, CMS, ZGC 등이 있습니다.
- 각 가비지 컬렉터는 특정 시나리오나 환경에 최적화되어 있습니다.
- 퍼포먼스 모니터링
- 실제 운영 환경에서 가비지 컬렉션의 성능과 영향을 모니터링하는 것은 중요합니다.
- 이를 위해 다양한 도구와 전략을 사용하여 시스템의 성능을 최적화할 수 있습니다.
Full GC에 대해서도 설명해 보세요
Full GC는 Java의 가비지 컬렉션 과정 중 하나로, 전체 힙 메모리인 Young Generation과 Old Generation 모두를 대상으로 사용되지 않는 객체를 회수하는 과정입니다.
주로 Old Generation 영역이 거의 차 있거나, 특정 경우에 명시적으로 System.gc()가 호출됐을 때 발생합니다.
특정적으로 Full GC가 진행되는 동안 애플리케이션의 모든 작업은 일시적으로 중지되는데, 이를 Stop-the-World라고 합니다.
이런 이유로 Full GC의 빈도가 높아지면 애플리케이션의 성능이 저하될 수 있습니다.
따라서, 메모리 설정을 조절하거나 적절한 가비지 컬렉터를 선택함으로써 Full GC의 발생 빈도나 지속 시간을 최적화하는 것이 중요합니다.
가비지 컬렉션의 동작과정에서 Stop-The-World란 무엇인가요?
Stop-the-World는 가비지 컬렉터 동작 과정 중 발생하는 현상으로 JVM이 애플리케이션의 모든 스레드를 일시 중단시키는 것을 의미합니다.
이 중단은 가비지 컬렉터가 효율적으로 메모리를 정리하고 정확하게 사용되지 않는 객체를 식별하기 위해 필요합니다.
Stop-the-World 이벤트는 모든 스레드가 정지되기 때문에 애플리케이션의 반응성에 영향을 줄 수 있습니다.
메모리 관리 및 직렬화
직렬화와 역직렬화에 대해 설명해 보세요.
- 직렬화
- 직렬화란 객체의 데이터를 파일에 저장하거나 네트워크를 통해 전송하기 위해 객체의 멤버 변수를 byte stream으로 변환하는 과정입니다.
- 자바에서는 'Serializable' 인터페이스를 구현함으로써 객체 직렬화를 수행할 수 있습니다.
- 역직렬화
- 반대로 byte stream을 다시 원래의 객체로 변환하는 과정을 의미합니다.
- 역직렬화를 수행하면, 직렬화를 통해 저장되었던 객체의 상태를 원래대로 복구할 수 있습니다.
SerialVersionUID를 선언해야 하는 이유에 대해 설명해 보세요.
JVM은 직렬화와 역직렬화를 하는 시점의 클래스에 대한 버전 번호를 부여하는데, 만약 그 시점에 클래스의 정의가 바뀌어 있다면 새로운 버전 번호를 할당하게 됩니다.
그래서 직렬화할 때 버전 번호와 역직렬화를 할 때의 버전 번호가 다르면 역직렬화가 불가능하게 될 수 있기 때문에 이런 문제를 해결하기 위해 SerialVersionUID를 사용합니다.
만약 직렬화할 때 사용한 SerialVersionUID의 값과 역직렬화하기 위해 사용했던 SerialVersionUID가 다르다면 InvalidClassException이 발생할 수 있습니다.
'👨💻 기술면접 > 자바' 카테고리의 다른 글
백엔드 기술면접 / 자바 기본 개요 (0) | 2023.10.03 |
---|
개인적으로 기술면접을 준비하면서 작성한 글입니다.
잘못된 내용이 기재되어 있으면 댓글로 말씀해 주시면 감사하겠습니다.. :)
지속적으로 확인하여 퀄리티 향상을 위해 힘써보겠습니다..
JVM 및 메모리 관리
자바의 동작 원리에 대해 설명해 보세요.
개발자는 [.java] 확장자 파일에 자바 소스 코드를 작성합니다. 이 파일은 자바 프로그램의 원시 코드를 포함합니다. 그리고 자바 컴파일러가 [.java] 파일의 소스 코드를 바이트 코드로 변환하며, [.class] 확장자 파일로 저장됩니다. 이 파일은 플랫폼 독립적인 중간 표현 형태입니다.
[.class] 파일들은 JVM 시작 또는 런타임 중에 필요할 때 클래스 로더에 의해 메모리에 로드됩니다. 이 과정은 필요한 클래스를 동적으로 로드하여 메모리에 배치합니다.그리고 JVM 내에 내장된 자바 인터프리터 또는 JIT 컴파일러는 [.class] 파일의 바이트 코드를 해석하거나 기계 코드로 컴파일합니다. 이 기계어 코드는 운영체제 위에서 직접 실행됩니다.JVM 내부에서 변환된 기계어는 OS 위에서 직접 실행됩니다. 이로 인해, JVM이 설치되어 있는 모든 플랫폼에서 동일한 바이트 코드가 동일하게 실행될 수 있습니다.
JVM에 대해 설명해 보세요.
JVM은 자바 바이트 코드 [. class] 파일을 실행하기 위한 가상 머신입니다.
JVM은 자바 프로그램의 플랫폼 독립성을 보장하는 핵심 요소입니다.
- 플랫폼 독립성
- JVM의 가장 중요한 특징은 플랫폼 독립성입니다.
- 바이트 코드가 특정 하드웨어나 운영체제에 종속되지 않기 때문에, Java 코드는 한 번 작성하면 어디에서나 실행될 수 있습니다.
- 대신 JVM은 해당 바이트 코드를 현지 시스템에 맞게 해석하고 실행합니다.
- 메모리 관리
- JVM 내부에는 가비지 컬렉터가 포함되어 있어, 더 이상 사용되지 않는 객체를 자동으로 회수하는 메모리 관리를 자동화하는 역할도 수행합니다.
- JVM의 아키텍처 및 주요 구성 요소
- Class Loader
- 바이트 코드를 로드하고 검증하는 역할을 합니다.
- Runtime Data Area
- JVM이 프로그램을 실행하는 동안 사용하는 메모리 영역입니다.
- 여기에는 메서드 영역, 힙 영역, 스택 영역, PC 레지스터, 그리고 네이티브 메서드 스택이 포함됩니다.
- Execution Engine
- 바이트 코드를 실행하는 역할을 합니다. Just-In-Time 컴파일러와 인터프리터가 여기에 포함됩니다.
- Native Interface
- JVM 내부의 Execution Engine과 외부의 Native Libraries를 연결합니다.
- Native Libraries
- 자바 API의 기본 구현을 제공하는 플랫폼 특정 라이브러리입니다.
- Class Loader
- 보안
- JVM은 플랫폼의 보안을 위해 몇 가지 중요한 메커니즘을 제공합니다.
- 예를 들면, 클래스 로더의 검증 기능을 통해 바이트 코드의 유효성을 검사하거나, 스택 검사를 통해 애플리케이션의 코드와 라이브러리 코드 사이의 상호 작용을 확인합니다.
자바 바이트 코드는 어떤 역할을 하는지 설명해 보세요.
자바 바이트 코드는 자바 소스 코드 [. java] 파일이 자바 컴파일러에 의해 컴파일되어 생성되는 중간 코드 [. class] 파일입니다. 자바의 플랫폼 독립성과 이식성을 보장하는 핵심 요소이며, 다양한 환경에서 동일한 프로그램 동작을 보장하는 역할을 합니다.
JDK와 JRE의 차이점에 대해 설명해 보세요.
JDK와 JRE는 Java 프로그램 개발과 실행에 필요한 도구들을 제공합니다.
- JDK(Java Development Kit)
- JDK는 개발자가 Java 프로그램을 개발하기 위해 필요한 도구 모음입니다.
- javac와 같은 도구를 포함하여, 자바 소스 코드 [. java] 파일을 바이트 코드 [. class] 파일로 컴파일하는 데 필요한 컴파일러도 포함됩니다.
- 또한, 개발 중에 필요한 다양한 유틸리티도 함께 제공됩니다.
- JDK 내부에는 JRE도 포함되어 있으므로, JDK를 설치하면 JRE도 함께 설치됩니다.
- JRE(Java Runtime Environment)
- JRE는 컴파일된 Java 프로그램을 실행하기 위해 필요한 환경을 제공합니다.
- 중요한 구성 요소로 JVM이 있으며, 바이트 코드를 현지 플랫폼의 기계 코드로 변환하고 실행합니다.
- JRE만 설치되어 있다면 Java 프로그램을 실행할 수 있지만 개발은 할 수 없습니다.
- 또한, Java API와 같은 기본 클래스 라이브러리도 포함됩니다.
클래스 로더는 무엇이며 어떤 역할을 하는지 설명해 보세요.
클래스 로더는 JVM 내에서 클래스 파일들을 로드하기 위한 역할을 수행합니다.
- 클래스 로더의 계층구조
- Java의 클래스 로더는 계층적으로 동작합니다.
- 이 계층구조 내에서, 여러 클래스들이 동작하며 대표적으로 Bootstrap ClassLoader, Extension ClassLoader 그리고 Application ClassLoader가 있습니다.
- Bootstrap ClassLoader는 JDK 내부의 핵심 자바 API들을 로드합니다.
- Extension ClassLoader는 확장 디렉토리의 클래스들을 로드합니다.
- Application ClassLoader는 환경 변수나 -cp, -classpath 옵션으로 지정된 경로의 클래스들을 로드합니다.
- 동적 로딩
- 클래스 로더의 능력 중 하나는 클래스를 동적으로 로드하는 것입니다.
- 이것은 자바가 런타임에 필요한 클래스를 로드할 수 있게 하므로, 모든 클래스가 애플리케이션 시작 시에 로드될 필요가 없습니다.
- 사용자 정의 클래스 로더
- 필요에 따라 개발자는 java.lang.ClassLoader 클래스를 상속받아 사용자 정의 클래스 로더를 구현할 수 있습니다.
- 이를 통해 특정 로직 또는 규칙에 따라 클래스를 로드할 수 있습니다.
즉, 클래스 로더는 자바 바이트 코드를 JVM에 동적으로 로드하며, 이를 위한 계층적 구조와 메커니즘을 제공합니다. 클래스 로딩 과정에서 로딩, 연결 그리고 초기화 단계를 거치며, 이를 통해 자바 프로그램의 유연성과 동적성이 보장됩니다.
JIT 컴파일러는 무엇인지 설명해 보세요.
JIT 컴파일러는 프로그램의 실행 시점에 바이트 코드나 중간 코드를 해당 시스템의 기계어로 컴파일하는 기술입니다.
- 장점
- 성능 향상 : 바이트 코드를 직접 해석하는 것보다, JIT 컴파일러에 의해 기계어로 변환된 코드는 훨씬 빠르게 실행됩니다.
- 런타임 최적화 : JIT 컴파일러는 프로그램이 실행되는 동안 수집한 정보를 바탕으로 더 효율적인 최적화를 수행합니다.
- 단점
- 초기 오버헤드 : 프로그램 시작 시 JIT 컴파일러는 바이트 코드를 기계어로 컴파일하는 과정에 시간을 소요하므로, 초기에 느릴 수 있습니다.
- 메모리 사용량 : JIT 컴파일 과정은 추가적인 메모리를 사용합니다.
JVM 메모리 영역(Heap, Stack 등)에 대해 설명해 보세요.
자바의 JVM위에서 실행되며, JVM은 메모리를 여러 영역으로 관리합니다.
주요 영역으로는 힙, 스택, 메서드 영역, PC 레지스터, 네이티브 메서드 스택 등이 있습니다.
- 힙(Heap)
- 힙은 객체의 인스턴스가 할당되는 영역입니다. 즉, new 키워드로 생성된 객체는 모두 이곳에 생성됩니다.
- 객체의 동적 데이터가 저장되는 영역으로, 대부분의 객체와 배열이 여기에 할당됩니다.
- 가비지 컬렉터가 활동하는 주요 영역이기도 하며, 사용되지 않는 객체는 이 영역에서 정리됩니다.
- 스택(Stack)
- 스택은 스레드별로 하나씩 존재하며, 메서드의 호출 정보, 지역 변수, 매개 변수 등이 저장되는 영역입니다.
- 각 메서드 호출에 따른 로컬 변수, 임시 데이터, 매개 변수, 변환 주소 등이 스택 프레임 형태로 쌓입니다.
- 메서드 호출이 종료되면, 해당 메서드에 대한 스택 프레임은 스택에서 제거됩니다.
- LIFO 구조를 갖고 변수에 새로운 데이터가 할당되면 이전 데이터는 사라집니다.
- 메서드 영역(Method Area)
- 클래스 파일의 바이트 코드, 변수 이름, 메서드 이름, 상수 풀 같은 메타 데이터와 정적 변수 등 클래스 수준의 정보가 저장됩니다.
- JVM 시작 시 생성되고 종료될 때까지 유지됩니다.
- PC 레지스터
- 현재 실행 중인 JVM 명령의 주소를 가집니다. 이 영역은 스레드마다 하나씩 생성됩니다.
- 네이티브 메서드 스택
- 자바 외의 언어로 작성된 네이티브 코드를 위한 메모리 영역입니다.
가비지 컬렉션에 대해 설명해 보세요.
가비지 컬렉션은 프로그램 실행 중에 동적으로 할당된 메모리 중 사용되지 않는 부분을 자동으로 회수하는 메모리 관리 기법입니다.
이로써 프로그래머는 직접 메모리를 해제하는 작업을 하지 않아도 되며, 이는 메모리 누수나 관련된 오류를 방지하는 데 큰 도움이 됩니다.
가비지 컬렉터에 대해 설명해 보세요.
가비지 컬렉터는 가비지 컬렉션 프로세스를 수행하는 JVM의 일부로, 자동 메모리 관리 시스템입니다.
가비지 컬렉터의 주 역할은 힙 메모리 영역에서 더 이상 사용되지 않는 객체를 식별하고, 그 객체들이 차지하고 있는 메모리를 해제하여 재사용 가능하게 만드는 것입니다.
- 작동 원리
- 참조 추적 : 가비지 컬렉터는 실행 중인 프로그램에서 더 이상 참조되지 않는 객체를 식별합니다.
- 메모리 회수 : 식별된 더 이상 사용되지 않는 객체의 메모리를 해제합니다.
- Stop-The-World
- 가비지 컬렉션 동작 시에는 JVM이 애플리케이션의 실행을 일시적으로 멈추는데, 이를 Stop-The-World라고 합니다.
- 이 시간 동안 애플리케이션의 모든 스레드가 일시 중지됩니다.
- 메모리 구조와 가비지 컬렉션
- Java의 힙 메모리는 크게 Young Generation과 Old Generation으로 나눠집니다.
- 대부분의 객체는 Young 영역에 생성되고, 일정 시간 이상 살아남은 객체는 Old 영역으로 이동됩니다.
- 가비지 컬렉터는 이 두 영역에 따라 다르게 동작합니다.
- 주요 가비지 컬렉터
- Java에서는 여러 가비지 컬렉터를 제공합니다.
- 주요한 것들로는 Parallel GC, G1 GC, CMS, ZGC 등이 있습니다.
- 각 가비지 컬렉터는 특정 시나리오나 환경에 최적화되어 있습니다.
- 퍼포먼스 모니터링
- 실제 운영 환경에서 가비지 컬렉션의 성능과 영향을 모니터링하는 것은 중요합니다.
- 이를 위해 다양한 도구와 전략을 사용하여 시스템의 성능을 최적화할 수 있습니다.
Full GC에 대해서도 설명해 보세요
Full GC는 Java의 가비지 컬렉션 과정 중 하나로, 전체 힙 메모리인 Young Generation과 Old Generation 모두를 대상으로 사용되지 않는 객체를 회수하는 과정입니다.
주로 Old Generation 영역이 거의 차 있거나, 특정 경우에 명시적으로 System.gc()가 호출됐을 때 발생합니다.
특정적으로 Full GC가 진행되는 동안 애플리케이션의 모든 작업은 일시적으로 중지되는데, 이를 Stop-the-World라고 합니다.
이런 이유로 Full GC의 빈도가 높아지면 애플리케이션의 성능이 저하될 수 있습니다.
따라서, 메모리 설정을 조절하거나 적절한 가비지 컬렉터를 선택함으로써 Full GC의 발생 빈도나 지속 시간을 최적화하는 것이 중요합니다.
가비지 컬렉션의 동작과정에서 Stop-The-World란 무엇인가요?
Stop-the-World는 가비지 컬렉터 동작 과정 중 발생하는 현상으로 JVM이 애플리케이션의 모든 스레드를 일시 중단시키는 것을 의미합니다.
이 중단은 가비지 컬렉터가 효율적으로 메모리를 정리하고 정확하게 사용되지 않는 객체를 식별하기 위해 필요합니다.
Stop-the-World 이벤트는 모든 스레드가 정지되기 때문에 애플리케이션의 반응성에 영향을 줄 수 있습니다.
메모리 관리 및 직렬화
직렬화와 역직렬화에 대해 설명해 보세요.
- 직렬화
- 직렬화란 객체의 데이터를 파일에 저장하거나 네트워크를 통해 전송하기 위해 객체의 멤버 변수를 byte stream으로 변환하는 과정입니다.
- 자바에서는 'Serializable' 인터페이스를 구현함으로써 객체 직렬화를 수행할 수 있습니다.
- 역직렬화
- 반대로 byte stream을 다시 원래의 객체로 변환하는 과정을 의미합니다.
- 역직렬화를 수행하면, 직렬화를 통해 저장되었던 객체의 상태를 원래대로 복구할 수 있습니다.
SerialVersionUID를 선언해야 하는 이유에 대해 설명해 보세요.
JVM은 직렬화와 역직렬화를 하는 시점의 클래스에 대한 버전 번호를 부여하는데, 만약 그 시점에 클래스의 정의가 바뀌어 있다면 새로운 버전 번호를 할당하게 됩니다.
그래서 직렬화할 때 버전 번호와 역직렬화를 할 때의 버전 번호가 다르면 역직렬화가 불가능하게 될 수 있기 때문에 이런 문제를 해결하기 위해 SerialVersionUID를 사용합니다.
만약 직렬화할 때 사용한 SerialVersionUID의 값과 역직렬화하기 위해 사용했던 SerialVersionUID가 다르다면 InvalidClassException이 발생할 수 있습니다.
'👨💻 기술면접 > 자바' 카테고리의 다른 글
백엔드 기술면접 / 자바 기본 개요 (0) | 2023.10.03 |
---|