2012-10-31 4 views
8

제 생각에 throw은 원시 jvm 명령입니다. 이것을 호출하면 JVM은 "현재 호출 스택이이를 catch 할 수 있는지 확인합니다". 그럴 수 없다면 자바는 반환이 호출 된 것처럼 거의 호출 스택을 팝합니다. jvm은 "현재 호출 스택이 그것을 catch 할 수 있는지 검사합니다"등등을 재귀 적으로 수행합니다.JVM은 런타임시 예외를 잡는 위치를 어떻게 알 수 있습니까?

내 질문 : 알고리즘 적으로 JVM이 호출 스택에서 주어진 예외를 잡을 수있는 위치를 알 수있는 방법은 무엇입니까? 코드 블록에 예외를 매핑하는 각 호출 스택 항목에 저장된 메타 데이터가 있습니까? 어떻게 든 추적 할 수있는 정적 데이터 구조가 힙에 있습니까? 어딘가에 데이터를 추적해야하기 때문입니다.

+1

관련 항목 : http://stackoverflow.com/questions/10301244/how-is-multicatch-implemented-in-java-7 – assylias

답변

9

JVM specification에 대한 세부 정보가 있습니다.

특히 section 4.7.3은 예외 테이블에 대한 세부 정보를 제공합니다. 예외 테이블은 어떤 명령어간에 어떤 예외가 발견되는지를 나타내는 일련의 항목입니다. Section 3.12에는 이에 대한 구체적인 예가 나와 있습니다.

이 메타 데이터가 JIT의 원시 코드로 매핑되는 방식은 물론 다른 문제입니다. 물론 구현에 따라 다릅니다. 예를 들어 네이티브 JITted 코드의 각 명령어 위치에서 원래 바이트 코드 위치로 다시 매핑 할 수 있습니다. 예외 테이블을 참조하여 올바른 핸들러를 찾을 수 있습니다.

+0

매우 흥미로운 :) – Mik378

1

일반적으로 말해서 : 예외가 발생하면 JVM이 "호출 스택"을 추출합니다. 이는 호출 스택의 각 레벨에서 실행되는 바이트 코드 또는 기계 명령어와 해당 위치와 연관된 클래스 및 메소드를 식별합니다.

그런 다음 예외가 발생하고 뒤로 작업하는 메소드로 시작하여 JVM은 try/catch 범위를 바이트 코드/시스템 명령어로 매핑하는 메소드의 테이블에서 (내부 클래스 객체에서) 찾습니다. 범위.

메서드에 대해 테이블에서 "일치"가 발견되고 발견 된 범위에서 모니터되는 클래스가 예외 유형 인 경우 예외를 설정 한 후 제어가 catch 진입 점으로 전송됩니다 매개 변수 위치에 정렬하여 catch 절을 참조 할 수 있습니다.

표에서 "일치"가 발견되지 않으면 호출 스택이 효과적으로 "팝"되고 스택의 맨 위에 다음 이전 방법이 배치되고 앞의 방법 표에서 "일치"에 대한 위 검색이 배치됩니다 try/catch 범위가 반복됩니다.

물론 이것은 지나치게 단순화되었습니다. finally 범위 (예 : 여러 개의 "가장자리"경우)를 처리하는 데 관련된 많은 추가 논리가 있습니다.

관련 문제