sun.misc.Unsafe가 존재하는 이유는 무엇이며 실제 환경에서 어떻게 사용할 수 있습니까? [닫은]

나는 다른 날에 sun.misc.Unsafe 패키지를 발견했고 그것이 할 수있는 것에 놀랐습니다.

물론 수업은 문서화되어 있지 않지만 수업을 사용해야 할 충분한 이유가 있는지 궁금합니다. 어떤 시나리오를 사용해야합니까? 실제 시나리오에서 어떻게 사용될 수 있습니까?

당신이 경우 또한, 필요를 뭔가가 아마 당신의 디자인으로 잘못 표시하지 않는 것이, 무엇입니까?

Java에 왜이 클래스가 포함됩니까?



답변

  1. VM “내재화” 즉, 잠금이없는 해시 테이블에 사용 된 CAS (Compare-And-Swap) 예 : sun.misc.Unsafe.compareAndSwapInt CAS에 대한 특별 지침이 포함 된 실제 JNI 호출을 기본 코드로 만들 수 있습니다.

    CAS에 대한 자세한 내용은 여기 ( http://en.wikipedia.org/wiki/Compare-and-swap)를 참조하십시오 .

  2. 호스트 VM의 sun.misc.Unsafe 기능을 사용하여 초기화되지 않은 객체를 할당 한 다음 생성자 호출을 다른 메소드 호출로 해석 할 수 있습니다.

  3. 기본 주소에서 데이터를 추적 할 수 있습니다. java.lang.Unsafe 클래스를 사용하여 객체의 메모리 주소를 검색하고 안전하지 않은 get / put 메소드를 통해 필드에서 직접 조작 할 수 있습니다!

  4. JVM에 대한 컴파일 시간 최적화 “매직”을 사용하는 고성능 VM. 낮은 수준의 작업이 필요합니다. 예 : http://en.wikipedia.org/wiki/Jikes_RVM

  5. 메모리 할당 sun.misc.Unsafe.allocateMemory 예 :-ByteBuffer.allocateDirect가 호출 될 때 DirectByteBuffer 생성자가 내부적으로이를 호출합니다.

  6. 호출 스택 추적 및 sun.misc로 인스턴스화 된 값으로 재생

  7. sun.misc.Unsafe.arrayBaseOffset 및 arrayIndexScale을 사용하여 대형 객체의 실시간 스캔, 업데이트 또는 이동 작업 비용을 제한하기 위해 대형 어레이를 더 작은 객체로 효율적으로 분할하는 기술인 arraylet을 개발할 수 있습니다.

  8. http://robaustin.wikidot.com/how-to-write-to-direct-memory-locations-in-java

여기 참조에 대한 자세한 내용 -http : //bytescrolls.blogspot.com/2011/04/interesting-uses-of-sunmiscunsafe.html


답변

일부 코드 검색 엔진에서 검색 을 실행 하면 다음 예제가 표시됩니다.

{@link Unsafe} 객체에 액세스 할 수있는 간단한 클래스입니다. 어레이에서 효율적인 CAS 작업을 수행하려면 {@link Unsafe} *가 필요합니다. {@link java.util.concurrent.atomic.AtomicLongArray}와 같이 {@link java.util.concurrent.atomic}의 버전에는 일반적으로 이러한 알고리즘에 필요하지 않으며 비용이 많이 드는 추가 메모리 순서 보증이 필요합니다. 대부분의 프로세서에서.

  • SoyLatte -OSX 용 Java 6 Javadoc 발췌

/ ** sun.misc의 기본 클래스 정적 필드의 안전하지 않은 FieldAccessors 리플렉션 코드의 관점에서 볼 때 8 가지 기본 유형과 Object라는 9 가지 유형의 필드 만 관찰됩니다. 생성 된 바이트 코드 대신 Unsafe 클래스를 사용하면 동적으로 생성 된 FieldAccessors의 메모리 및로드 시간이 절약됩니다. * /

  • 스파이크 소스

/ * 와이어를 통해 전송되는 FinalFields .. 수신 측에서 개체를 비 정렬 화하고 다시 만드는 방법? 최종 필드에 대한 값을 설정하므로 생성자를 호출하고 싶지 않습니다. 발신자 쪽과 마찬가지로 최종 필드를 다시 만들어야합니다. 안전하지 않은 일. * /

다른 많은 예제가 있습니다. 위의 링크를 따르십시오 …


답변

흥미롭게도, 나는이 수업에 대해 들어 본 적이 없습니다.

한 가지 중요한 점 은 Unsafe # setMemory 를 사용하여 중요한 정보가 포함 된 버퍼 (암호, 키 등)를 0으로 만드는 것입니다. “불변의”객체의 필드에도이 작업을 수행 할 수 있습니다 (그런데 평범한 오래된 리플렉션도 여기서 트릭을 수행 할 수 있습니다). 나는 보안 전문가가 아니므로 소금 한 덩어리로 이것을 가져 가십시오.


답변

참조 추적에 이클립스를 사용하는 Java 1.6.12 라이브러리에 대한 매우 간단한 분석을 기반으로, 모든 유용한 기능이 Unsafe유용한 방식으로 노출되는 것처럼 보입니다 .

CAS 작업은 Atomic * 클래스를 통해 노출됩니다. 메모리 조작 기능은 DirectByteBuffer Sync 명령어 (park, unpark)를 통해 노출되며 AbstractQueuedSynchronizer를 통해 노출되며 이는 Lock 구현에서 사용됩니다.


답변

Unsafe.throwException- 확인 된 예외를 선언하지 않고 던질 수 있습니다.

리플렉션 또는 AOP를 처리하는 경우에 유용합니다.

사용자 정의 인터페이스에 대한 일반 프록시를 작성한다고 가정하십시오. 또한 사용자는 인터페이스에서 예외를 선언하기 만하면 특수한 경우에 함침에 의해 발생하는 예외를 지정할 수 있습니다. 그런 다음 이것이 인터페이스의 동적 구현에서 확인 된 예외를 발생시키는 유일한 방법입니다.

import org.junit.Test;
/** need to allow forbidden references! */ import sun.misc.Unsafe;

/**
 * Demonstrate how to throw an undeclared checked exception.
 * This is a hack, because it uses the forbidden Class {@link sun.misc.Unsafe}.
 */
public class ExceptionTest {

    /**
     * A checked exception.
     */
    public static class MyException extends Exception {
        private static final long serialVersionUID = 5960664994726581924L;
    }

    /**
     * Throw the Exception.
     */
    @SuppressWarnings("restriction")
    public static void throwUndeclared() {
        getUnsafe().throwException(new MyException());
    }

    /**
     * Return an instance of {@link sun.misc.Unsafe}.
     * @return THE instance
     */
    @SuppressWarnings("restriction")
    private static Unsafe getUnsafe() {
        try {

            Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
            singleoneInstanceField.setAccessible(true);
            return (Unsafe) singleoneInstanceField.get(null);

        } catch (IllegalArgumentException e) {
            throw createExceptionForObtainingUnsafe(e);
        } catch (SecurityException e) {
            throw createExceptionForObtainingUnsafe(e);
        } catch (NoSuchFieldException e) {
            throw createExceptionForObtainingUnsafe(e);
        } catch (IllegalAccessException e) {
            throw createExceptionForObtainingUnsafe(e);
        }
    }

    private static RuntimeException createExceptionForObtainingUnsafe(final Throwable cause) {
        return new RuntimeException("error while obtaining sun.misc.Unsafe", cause);
    }


    /**
     * scenario: test that an CheckedException {@link MyException} can be thrown
     * from an method that not declare it.
     */
    @Test(expected = MyException.class)
    public void testUnsingUnsaveToThrowCheckedException() {
        throwUndeclared();
    }
}

답변

안전하지 않은 클래스

안전하지 않은 저수준 작업을 수행하기위한 방법 모음. 클래스와 모든 메소드는 공용이지만이 클래스의 사용은 신뢰할 수있는 코드 만 인스턴스를 얻을 수 있으므로 제한됩니다.

그것을 사용하는 java.util.concurrent.atomic수업 중 하나입니다 :


답변

효율적인 메모리 복사 (짧은 블록의 경우 System.arraycopy ()보다 복사 속도가 빠름); Java LZFSnappy 코덱에서 사용됩니다 . 바이트 단위로 복사하는 것보다 빠른 ‘getLong’및 ‘putLong’을 사용합니다. 16/32/64 바이트 블록과 같은 것을 복사 할 때 특히 효율적입니다.