2013-05-04 1 views
0

Java 힙은 객체 만 저장하고 스택은 원시 데이터와 객체 참조 만 저장합니다.자바에서는 객체 필드에 대한 작업이 스택을 우회 할 수 있습니까?

A.a = B.b을 고려하십시오. 여기에서 A.aB.bint입니다.

제 생각에 JVM은 힙에서 스택으로 A.a의 값을 가져온 다음 힙에있는 B.b으로 값을 가져옵니다. 힙에있는 데이터를 변경하는 유일한 방법은 스택에서 값을 PUT하는 것입니다.

제 질문은 스택없이 Java 힙에 대한 데이터를 조작 할 수있는 방법이 있습니까? 예 : A.a의 값을 스택 작업없이 B.b으로 직접 복사합니다.

"JVM 구현에 따라 다르다"라고 말하면 제 질문은 달빅에 관한 것입니다.

답변

1

JIT를 고려할 때 상황이 복잡해집니다.내 질문은 자바 컴파일러에 대해 실제로하지 JVM 생각

당신은 당신이 거의 최적화를 수행하고 바이트 코드에 매우있는 코드의 거의 직역을 제공한다고 가정한다 javac 생각하는 경우 스택 기반.

실제로 바이트 코드는 예제에서 제시 한 것보다 더 많은 스택을 사용하게됩니다. 대신 하나 개의 스택 동작, 그것도 값 레지스터를 사용하지 않도록

반면에 JIT 3. 얻어이를 최적화 할 수 개념적있다

push B 
getAndPushField b 
push A 
popAndSetField a 

즉, 같은 동작을한다. 프로세서에 따라 다름

// R3 contains A, R7 contains B, 
// a starts at the 14th byte 
// b start at the 16th byte 
MOVI [R3+14], [R7+16] 
0

JVM의 구현에 의존하지 않습니다. 스택을 통하는 것 이외의 방법은 제공하지 않는 Java Virtual Machine Specification에 의존합니다.

+0

추상 기계에 대해서만 생각하고 실제 기계에서 발생하는 일은 무시한다고 가정합니다. – delnan

+1

답변 해 주셔서 감사합니다. 나는 counter-example을 가지고 있지만 확실치 않다 : 객체의'clone()'을 고려한다. malloc()과 memcpy()를 사용하여 Java 힙에 새로운 객체를 생성 한 후 참조를 반환하십시오. 이 방법으로, 실제로'old_obj.field'의 값을'new_obj.field'에 복사합니다. 우회하는 것입니까? –

2

JVM이라는 추상 기계 (실제 하드웨어에 매핑하여 추상 기계를 구현하고 동일한 이름을 사용하는 다양한 소프트웨어와 혼동하지 말 것)에 대해서는 A.a = B.b이 실제로 값을로드합니다 스택에 B.b이 있으면 A.a에 저장합니다. 추상적 기계가 당신을 말할 수있는 이름 그러나1

는, 이것은 단지 의미에 대해 생각하는 방법입니다. 구현은 프로그램의 효과를 보존하는 한 원하는 모든 것을 수행 할 수 있습니다. 대부분의 구현체는 JVM 명령어를 실제로 해석하지 않고 실행중인 CPU의 머신 코드로 컴파일합니다. 퍼포먼스 나 메모리 트래픽이 걱정된다면, 더 깊이 들어가야합니다.

컴파일 할 때 JVM 스택은 대부분의 물리적 CPU가 사용하는 레지스터를 위해 대부분 폐기됩니다. 사용할 수있는 레지스터가 충분하지 않으면 하드웨어 스택 (JVM 스택과 구별됩니다!)을 사용할 수도 있습니다. 그러나 나는 빗 나간다. 대부분의 아키텍처에서는 한 메모리 위치에서 다른 메모리 위치로 이동할 수있는 지침이 없습니다 (Assembly: MOVing between two memory addresses 참조). 그러나 하드웨어 스택도 메모리이므로 실제적으로 은 불가능합니다. heap -> stack -> heap. 대신 코드가 메모리에서 레지스터로 값을로드 한 다음 레지스터에서 메모리에 값을 저장한다는 것을 알 수 있습니다.

마지막으로 개체 A와 B의 수명이 짧고 별칭이 지정되지 않은 경우 해당 필드가 스택이나 레지스터로 끝나기도합니다. 그런 다음이 작업은 훨씬 간단 해집니다 (또는 효과가없는 경우 완전히 제거 될 수도 있음).

이 두 단계는 실제로 각각 여러 개의 JVM 명령어를 사용하지만 여기서는 중요하지 않습니다.

+0

답변 해 주셔서 감사합니다. JIT를 고려할 때 상황은 복잡해집니다. 제 질문은 자바 컴파일러가 아니라 JVM에 관한 것이라고 생각합니다. 다시 한 번 감사드립니다. –

관련 문제