[java] JVM이 여전히 꼬리 호출 최적화를 지원하지 않는 이유는 무엇입니까?

2 년 후 않습니다 – 더 – JVM이 – 꼬리 – 전화 – 최적화를 방지 하는있을 것 같습니다 프로토 타입 구현MLVM이 지금 얼마 동안 “프로토 80 %”로 기능을 나열하고있다.

테일 콜을 지원하는 데 썬 / 오라클 측의 적극적인 관심이 없나요? 아니면 JVM 에서 언급 한 것처럼 테일 콜이 “[…] 모든 기능 우선 순위 목록에서 2 위를 차지할 운명이었던 것일까 요? Language Summit ?

누군가 MLVM 빌드를 테스트하고 그것이 얼마나 잘 작동하는지에 대한 인상을 공유 할 수 있다면 정말로 관심이있을 것입니다.

업데이트 : Avian 과 같은 일부 VM은 문제없이 적절한 테일 콜을 지원합니다.



답변

Java 코드 진단 : Java 코드의 성능 향상 ( alt )은 JVM이 테일 호출 최적화를 지원하지 않는 이유를 설명합니다.

그러나 꼬리 재귀 함수를 자동으로 간단한 루프로 변환하는 방법은 잘 알려져 있지만 Java 사양에서는이 변환을 수행 할 필요가 없습니다. 아마도 요구 사항이 아닌 한 가지 이유는 일반적으로 객체 지향 언어에서 정적으로 변환 할 수 없기 때문입니다. 대신 꼬리 재귀 함수에서 단순 루프로의 변환은 JIT 컴파일러에 의해 동적으로 수행되어야합니다.

그런 다음 변환되지 않는 Java 코드의 예를 제공합니다.

따라서 목록 3의 예에서 볼 수 있듯이 정적 컴파일러가 언어의 의미를 유지하면서 Java 코드에서 꼬리 재귀 변환을 수행 할 것으로 기대할 수 없습니다. 대신 JIT에 의한 동적 컴파일에 의존해야합니다. JVM에 따라 JIT는이를 수행하거나 수행하지 않을 수 있습니다.

그런 다음 JIT가이를 수행하는지 확인하는 데 사용할 수있는 테스트를 제공합니다.

당연히이 문서는 IBM 문서이므로 다음과 같은 플러그가 포함됩니다.

이 프로그램을 Java SDK 몇 개로 실행했는데 결과는 놀라웠습니다. 버전 1.3 용 Sun의 Hotspot JVM에서 실행하면 Hotspot이 변환을 수행하지 않는다는 것을 알 수 있습니다. 기본 설정에서 스택 공간은 내 컴퓨터에서 1 초 이내에 소진됩니다. 반면에 IBM의 1.3 버전 용 JVM은 문제없이 순조롭게 진행되어 이러한 방식으로 코드를 변환합니다.


답변

Java에서 TCO를 구현하지 않은 (그리고 어려운 것으로 간주되는) 이유 중 하나는 JVM의 권한 모델이 스택에 민감하므로 테일 호출이 보안 측면을 처리해야한다는 것입니다.

나는 이것이 Clements와 Felleisen [1] [2]에 의해 장애물이 아니라고 생각하며 질문에 언급 된 MLVM 패치도 그것을 다루고 있다고 확신합니다.

나는 이것이 당신의 질문에 대답하지 않는다는 것을 알고 있습니다. 흥미로운 정보를 추가하는 것뿐입니다.

  1. http://www.ccs.neu.edu/scheme/pubs/esop2003-cf.pdf
  2. http://www.ccs.neu.edu/scheme/pubs/cf-toplas04.pdf


답변

이미 이것을 알고 있을지 모르지만 Java 언어가 실제로 프로그래머에게 스택 추적을 노출하기 때문에 기능이 들리는 것처럼 사소한 것은 아닙니다.

다음 프로그램을 고려하십시오.

public class Test {

    public static String f() {
        String s = Math.random() > .5 ? f() : g();
        return s;
    }

    public static String g() {
        if (Math.random() > .9) {
            StackTraceElement[] ste = new Throwable().getStackTrace();
            return ste[ste.length / 2].getMethodName();
        }
        return f();
    }

    public static void main(String[] args) {
        System.out.println(f());
    }
}

“테일 콜”이 있더라도 최적화되지 않을 수 있습니다. (이 경우 되고 최적화, 여전히 프로그램이 의존의 의미 이후 전체 호출 스택의 부기가 필요합니다.)

기본적으로 이것은 하위 호환성을 유지하면서이를 지원하기가 어렵다는 것을 의미합니다.


답변

Java는 당신이 상상할 수있는 최소한의 기능적 언어 이지만 (글쎄요, 아마도 아닐 것입니다 !) 이것은 Scala 와 같은 JVM 언어에 큰 이점이 될 것 입니다.

내 관찰에 따르면 JVM을 다른 언어 용 플랫폼으로 만드는 것은 Sun의 우선 순위 목록에있는 것 같지 않았으며 이제 Oracle의 경우에도 마찬가지입니다.


답변