기존 Java 프로그래밍에서는 더 이상 Java 객체나 메모리 위치를 처리할 필요가 없습니다. 포럼에서 이 문제를 논의할 때 가장 먼저 떠오르는 질문은 왜 Java 객체의 주소를 알아야 합니까?입니다. 유효한 질문입니다. 그러나 과거에는 우리가 재판을 실시할 권리를 보유했습니다. 미지의 영역에서 질문을 탐구하는 데는 아무런 문제가 없습니다. 나는 sun 회사 패키지를 사용하여 실험을 생각해 냈습니다. Unsafe는 sun.misc에 속하는 패키지입니다. 어쩌면 이 패키지가 여러분에게 다소 생소할 수도 있습니다. 소스 코드와 메소드를 살펴보면 제가 말하는 내용을 아실 것입니다.
Java의 보안 관리는 메모리를 그렇게 쉽게 망칠 수 없도록 충분한 숨김 기능을 제공합니다. 첫 번째 단계로 나는 Java 객체의 메모리 위치를 얻는 것을 생각했습니다. 탐색하기 전까지 나는 Java에서 객체의 주소 위치를 찾는 것이 불가능하다고 100% 확신했습니다.
Sun의 Unsafe.java API 문서는 objectFieldOffset 메소드를 사용하여 주소에 액세스할 수 있음을 보여줍니다. 이 메소드는 "보고서의 클래스가 자신의 위치를 저장 공간의 특정 영역에 할당한다"고 말하는 것 같습니다. "이것은 단지 쿠키가 안전하지 않은 힙 메모리에 전달되는 접근자일 뿐입니다."라고 말하는 것 같습니다. 어쨌든, 클래스 저장소에서 객체가 저장되는 메모리 위치를 할당할 수 있습니다. 우리가 얻는 것은 객체의 절대적인 물리적 메모리 주소가 아니라고 주장할 수도 있습니다. 그러나 우리는 논리 메모리 주소를 얻었습니다. 다음 프로그램은 귀하에게 큰 관심을 가질 것입니다!
첫 번째 단계로 Unsafe 클래스의 개체를 가져와야 합니다. 생성자는 비공개이기 때문에 이는 어렵습니다. 안전하지 않은 객체를 반환하는 getUnsafe라는 메서드가 있습니다. Java 보안 관리를 위해서는 소스 코드 권한을 부여해야 합니다. 나는 약간의 반성을 사용하고 인스턴스를 얻었습니다. 인스턴스를 얻는 더 좋은 방법이 있다는 것을 알고 있지만 보안 관리를 우회하기 위해 다음과 같은 방법을 선택했습니다.
안전하지 않은 개체를 사용하려면 objectFieldOffset 및 staticFieldOffset을 호출하면 됩니다. 결과는 클래스의 메모리 할당 주소입니다.
다음 예제 프로그램은 JDK1.6에서 실행될 수 있습니다.
공개 클래스 ObjectLocation {
개인 정적 int 사과 = 10;
개인 int 오렌지 = 10;
public static void main(String[] args)에서 예외가 발생합니다.
안전하지 않음 unsafe = getUnsafeInstance();
필드 appleField = ObjectLocation.class.getDeclaredField("apple");
System.out.println("Apple의 위치: "
+ unsafe.staticFieldOffset(appleField));
Field orangeField = ObjectLocation.class.getDeclaredField("orange");
System.out.println("오렌지의 위치: "
+ unsafe.objectFieldOffset(orangeField));
}
private static Unsafe getUnsafeInstance()에서 SecurityException이 발생합니다.
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (안전하지 않음) theUnsafeInstance.get(Unsafe.class);
}
}