안전하지 않은 수업은 무엇입니까?
Java는 원래 안전한 통제 환경으로 설계되었습니다. 그럼에도 불구하고 Java Hotspot에는 여전히 메모리와 스레드를 직접 조작 할 수있는 일부 저수준 작업을 제공하는 "백도어"가 포함되어 있습니다. 이 백도어 클래스 인 Sun.misc.unsafe-는 java.nio 및 java.util.concurrent와 같은 JDK의 자체 패키지에서 널리 사용됩니다. 그러나이 백도어는 생산 환경에서 전혀 권장되지 않습니다. 이 API는 매우 안전하지 않고 가볍고 불안정하기 때문입니다. 이 불안정한 클래스는 핫스팟 JVM의 내부 구조를 볼 수 있으며 수정할 수 있습니다. 때로는 C ++ 디버깅없이 가상 머신의 내부 구조를 배우는 데 사용될 수 있으며 때로는 성능 모니터링 및 개발 도구로 사용될 수 있습니다.
소개
최근에 나는 Java 동시 패키지의 소스 코드를보고 있었고 마법의 안전하지 않은 클래스를 발견했습니다. 나는 그것을 조심스럽게 공부하고 여기에서 당신과 공유했습니다.
안전하지 않은 클래스는 Sun.Misc 패키지 아래에 있으며 Java 표준에 속하지 않습니다. 그러나 널리 사용되는 고성능 개발 라이브러리를 포함한 많은 기본 Java 클래스 라이브러리는 Netty, Cassandra, Hadoop, Kafka 등과 같은 안전하지 않은 클래스를 기반으로 개발되었습니다. 안전하지 않은 클래스는 Java 운영 효율성을 향상시키고 Java 언어의 기본 운영 기능을 향상시키는 데 큰 역할을합니다.
안전하지 않은 클래스는 Java에게 C 언어로 포인터와 같은 메모리 공간을 작동 할 수있는 기능을 제공하고 포인터 문제를 가져옵니다. 안전하지 않은 클래스를 과도하게 사용하면 오류가 발생할 가능성이 높아 지므로 Java는이를 사용하는 것이 좋지 않으며 공식 문서는 거의 없습니다. Oracle은 Java 9에서 안전하지 않은 클래스를 제거 할 계획이며, 그렇다면 너무 클 것입니다.
일반적으로 명확한 목적을 가지고 있고 그것을 심도있게 이해하지 않는 한 안전하지 않은 클래스를 사용하지 않는 것이 가장 좋습니다. 안전하지 않은 클래스를 사용하려면 몇 가지 까다로운 방법을 사용해야합니다. 안전하지 않은 클래스는 싱글 톤 패턴을 사용하며 정적 방법 getUnsafe ()를 통해 얻어야합니다. 그러나 안전하지 않은 클래스는이를 제한했습니다. 일반적인 호출 인 경우 SecurityException 예외가 발생합니다. 메인 클래스 로더가로드 한 클래스만이 방법을 호출 할 수 있습니다. 소스 코드는 다음과 같습니다.
공개 정적 안전하지 않은 getUnsafe () {class var0 = reclection.getCallerClass (); if (! vm.issystemdomainloader (var0.getClassLoader ())) {Throw New SecurityException ( "안전하지 않은"); } else {return theunsafe; }}BootClassPath 매개 변수 설정과 같은 메인 클래스 로더를 사용하여 사용자 코드를로드하는 몇 가지 방법이 있습니다. 그러나 더 간단한 방법은 다음과 같이 Java 반사를 사용하는 것입니다.
필드 f = unsafe.class.getDeclaredfield ( "Theunsafe"); f.setAccessible (true); 안전하지 않은 안전하지 않은 = (안전하지 않은) f.get (null);
안전하지 않은 인스턴스를 얻은 후에는 원하는대로 할 수 있습니다. 안전하지 않은 클래스는 다음과 같은 기능을 제공합니다.
1. 메모리 관리. 메모리 할당, 메모리 자유 등을 포함하여
이 부분은 Allocatememory (Allocatememory), Reallocatememory (Reallocatememory), CopyMemory (Copy Memory), Freememory (Free Memory), GetAddress (GetGet 메모리 주소), 주소 크기, Pagesize, GetInt (메모리 주소에 의해 지적), GetIntvolatile (감히 지적)이 포함됩니다. putint (정수를 지정된 메모리 주소에 쓰기), putintvolatile (정수를 지정된 메모리 주소에 쓰고 휘발성 시맨틱을 지원 함), putorderedint (정수를 지정된 메모리 주소, 순서 또는 지연 메소드에 쓰기). getxxx 및 putxxx에는 다양한 기본 유형의 작업이 포함되어 있습니다.
copymemory 방법을 사용하여 각 객체의 클론 방법을 구현하지 않고 일반 객체 복사 방법을 구현할 수 있습니다. 물론,이 일반적인 방법은 물체의 얕은 복사 만 달성 할 수 있습니다.
2. 비 전통적인 객체 인스턴스화.
AllocationInstance () 메소드는 인스턴스를 생성하는 또 다른 방법을 제공합니다. 일반적으로 우리는 새로운 또는 반사로 물체를 인스턴스화 할 수 있습니다. AllocationInstance () 메소드를 사용하여 생성자 및 기타 초기화 방법을 호출하지 않고 개체 인스턴스를 직접 생성하십시오.
이는 물체를 사로화하여 생성자를 호출하지 않고 최종 필드를 재건하고 설정할 수있을 때 유용합니다.
3. 운영 클래스, 객체 및 변수.
이 부분에는 staticfieldoffset (정적 도메인 오프셋), 정의 클래스 (정의 클래스), 정의 익명 클래스 (정의 익명 클래스), EnseReclassInitialized (클래스 초기화 확인), ObjectfieldOffset (객체 도메인 오프셋) 및 기타 메소드가 포함됩니다.
이 방법을 통해 객체의 포인터를 얻을 수 있습니다. 포인터를 상쇄함으로써, 우리는 포인터가 지적한 데이터를 직접 수정할 수있을뿐만 아니라 (개인이라도) JVM이 이미 쓰레기를 고려하고 재활용 할 수있는 객체를 찾을 수도 있습니다.
4. 배열 작동.
이 부분에는 ArrayBaseOffset (배열의 첫 번째 요소의 오프셋 주소를 가져옵니다), ArrayIndexScale (배열에서 요소의 증분 주소를 가져옵니다) 등이 포함되며 ArrayBaseOffset은 ArrayIndExScale과 함께 사용되며 메모리의 배열에서 각 요소의 위치를 찾을 수 있습니다.
Java의 최대 배열 값은 정수이기 때문에 Max_Value이므로 안전하지 않은 클래스의 메모리 할당 방법을 사용하여 초대형 어레이를 구현할 수 있습니다. 실제로 이러한 데이터는 C 배열로 간주 될 수 있으므로 적절한 시간에 메모리를 해제하는 데주의를 기울여야합니다.
5. 멀티 스레드 동기화. 잠금 장치, CAS 작동 등을 포함하여
이 부분에는 MoniterEnter, trymonitorenter, monitorexit, compareandswapint, compareandswap 및 기타 방법이 포함됩니다.
그중에서도 Moniterenter, TrymonitorEnter 및 MonitoreXit은 더 이상 사용되지 않은 것으로 표시되어 권장되지 않습니다.
안전하지 않은 클래스의 CAS 작업이 가장 많이 사용될 수 있으며 Java의 잠금 장치를위한 새로운 솔루션을 제공합니다. 예를 들어, Atomicinteger 및 기타 클래스는 모두이 방법을 통해 구현됩니다. CompareAndswap 방법은 원자이며, 이는 무거운 잠금 메커니즘을 피하고 코드 효율을 향상시킬 수 있습니다. 이것은 낙관적 인 잠금으로, 대부분의 경우 경주 조건이 없으며, 작동이 실패하면 성공할 때까지 계속 다시 시도 할 것입니다.
6. 일시 중단 및 복원.
이 부분에는 Park, Unpark 및 기타 방법이 포함됩니다.
공원 방법을 통해 스레드를 일시 중단하십시오. Park에 전화하면 타임 아웃 또는 인터럽트가 발생할 때까지 스레드가 차단됩니다. Unpark는 보류중인 스레드를 종료하여 정상으로 복원 할 수 있습니다. 전체 동시성 프레임 워크의 스레드에서의 일시 중단 작업은 Locksupport 클래스에 캡슐화됩니다. Locksupport 클래스에는 다양한 버전의 팩 방법이 있지만 결국에는 안전하지 않은 .park () 메소드가 호출됩니다.
7. 메모리 장벽.
이 부분에는 Loadfence, Storfence, Fullfence 및 기타 방법이 포함됩니다. 코드 재정렬을 피하기 위해 메모리 장벽을 정의하기 위해 Java 8에 새로 도입되었습니다.
loadfence ()는 메모리 장벽 전에 메소드가 완료되기 전에 모든로드 작업이 완료됨을 의미합니다. 마찬가지로, Storefence ()는이 메소드 전에 모든 매장 작업이 메모리 배리어 전에 완료됨을 의미합니다. Fullfence ()는 메모리 장벽 전에 방법이 완료되기 전에 모든 부하 및 저장 작업이 완료되었음을 의미합니다.
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.