자바 에서 다른 종류의 메모리 사용 방법

3984 단어 자바
sun.misc.Unsafe 는 자바 의 편리 한 문 을 열 어 줍 니 다.자바 가 허락 하지 않 는 일 을 많이 할 수 있 습 니 다.아주 특별한 장면 에서 도 유용 합 니 다.99 퍼센트 의 경우,너 는 그것 을 사용 하 는 것 을 피해 야 하지만,어떤 보기 드 문 상황 에 서 는 그것 만 이 문 제 를 해결 할 수 있다.
본 고 는 OpenHFT 에서 의 사용 장면 과 자바 9 에서 어떤 기능 을 보고 싶 은 지 설명 한다.많은 메모리 에 접근 하면 서도 GC 에 영향 을 주지 않 으 려 면 언 세 이 프 를 사용 하기에 특히 적합 하 다.프로 세 스 간 에 메모 리 를 공유 하 는 동시에 현저 한 지출 을 원 하지 않 습 니 다.자바 에 서 는 이런 방법 밖 에 없습니다.
메모리 할당 및 방출
public native long allocateMemory();
public native void freeMemory(long address);

    너 는 이 두 가지 방법 으로 모든 크기 의 메모 리 를 분배 할 수 있다.Integer.MAX 를 받 지 않 습 니 다.VALUE 바이트 의 크기 제한 입 니 다.원본 메모리 로 되 돌아 갑 니 다.필요 하 다 면 경계 검 사 를 할 수 있 습 니 다.예 를 들 어 Bytes.writeUTF(String)는 인 코딩 된 문자열 의 길 이 를 계산 하고 다음 문자열 을 수용 할 지 여 부 를 검사 합 니 다.물론 한 번 만 검사 하고 바이트 마다 검사 하지 않 습 니 다.
java.lang 에 도 비슷 한 Cleaner 클래스 가 있 습 니 다.DirectByteBuffer 는 메모리 가 풀 렸 는 지 확인 하기 위해 사용 합 니 다.하지만 이런 종 류 는 이런 핵심 적 인 곳 에 두 어 서 는 안 된다.
원본 메모리 에 접근
public native Xxx getXxx(Object, long offset); // intrinsic
public native void putXxx(Object, long offset);// intrinsic

이 두 그룹의 방법 중,쌓 인 메모리 에 접근 할 때,Object 는 비어 있 고,offset 는 실제 주소 입 니 다.그것들 을 내부 함수 로 하 는 JVM 에 서 는 기계 명령 하나만 으로 원본 메모리 에 접근 할 수 있다.이것 은 메모리 접근 의 효율 을 크게 향상 시 켰 다.
이러한 접근 방식 의 문 제 는 데이터 구조 안의 각 필드 의 분 포 를 스스로 유지 해 야 한 다 는 것 이다.java.lang 라 이브 러 리 의 해결 방법 은 getter 와 setter 방법 을 정의 한 다음 실행 할 때 구체 적 인 실현 을 생 성 하 는 것 입 니 다.대상 이 쌓 여 있 든 쌓 여 있 든 간 에 getter 와 setter 를 통 해 직접 방문 하면 된다 는 것 이다.
스 레 드 메모리 에 안전하게 접근
public native Xxx getVolatileXxx(Object, long offset); // intrinsic
public native void putOrderedXxx(Object, long offset); // intrinsic

이 두 가지 방법 이 있 으 면 게 으 른 로 딩 집합 을 통 해 한 필드 를 volatile 형식 으로 모 의 할 수 있 습 니 다.스 레 드 는 이 집합 을 통 해 값 을 설정 하 는 속도 가 더 빠 를 것 입 니 다.그러나 이 스 레 드 가 빠르게 값 을 읽 으 면 오래된 값 을 읽 을 수 있 습 니 다.해결 방법 은 방금 쓴 값 을 읽 지 않 는 것 이다.
프로 세 스 에서 메모 리 를 공유 할 때 이 두 그룹의 방법 은 특히 유용 하 다.
CAS 조작
public native boolean compareAndSwapXxxx(Object, long offset, Xxx expected, Xxx setTo)

더미 밖의 자 물 쇠 를 만 들 려 면 이 방법 이 빠 질 수 없다.프로 세 스 간 에 안전하게 데 이 터 를 공유 하 는 것 도 가장 효율 적 인 방식 이다.내 가 Haswell 프로세서 i7-4500 에서 한 테스트 를 보면 같은 기계 의 두 프로 세 스 간 의 통신 왕복 지연 이 상당히 좋 았 다.

   
       
           
           
       
       
           
           
       
       
           
           
       
       
           
           
       
   
TCP - 9 micro-seconds.
FileLocks - 5.5 micro-seconds.
CAS - 0.12 micro-seconds.
Ordered write - 0.02 micro-seconds.

퇴적 대상 의 분배
public native Object allocateInstance(Class clazz);

클래스 의 반 서열 이 있 을 때,당신 은 당연히 클래스 안의 값 이 서열 전의 모습 으로 회복 되 기 를 바 랍 니 다.하지만 지금 구조 방법 에 서 는 작은 문제 가 있 을 수 있 습 니 다.
4.567915.에서 이 문 제 를 언급 한 적 이 있다.새로운 대상 을 만 들 기 위해 서 는 구조 적 방법 을 전혀 사용 하지 않 는 것 이 해결책 이다.이것 은 당신 이 데이터 의 정확성 을 충분히 믿 어야 한 다 는 것 을 설명 합 니 다.장점 은 바로 사용 하기 쉽 고 도대체 어떤 구조 방법 으로 대상 을 예화 하 는 지 에 관심 을 가지 지 않 아 도 된다 는 것 입 니 다.
결론.
끼 워 넣 은 데이터 베 이 스 는 별도의 네트워크 비용 이 없 기 때문에 요청 지연 에 있어 서 분포 식 데이터 베이스 보다 훨씬 좋 습 니 다.나 는 차세 대 저 지연 데이터 베 이 스 는 내장 형 데이터 뱅 크 의 성능 뿐만 아니 라 프로 세 스 간 에 도 공유 할 수 있 을 뿐만 아니 라 업데이트 와 조회 의 응답 시간 도 밀리초 이하 일 수 있다 고 믿는다.
자 바 는 그것 을 실현 하지 않 을 이유 가 없다.자바 사용자 에 게 로 컬 인터페이스의 성능 은 가장 좋다.JNI 가 필요 하지 않 거나 자바 와 C 사이 의 1 층 전환 이 필요 하지 않 기 때문이다.
번역자 주:글 은 독자 가 Unsafe 에 대해 어느 정도 이해 하고 인식 한다 고 가정 하고 더 상세 한 설명 은 주목 하 시기 바 랍 니 다.
본 블 로그 의 후속 글
글 은 동시에 본인 의 블 로그 에 발표 되 었 습 니 다.
JEP 187: Serialization 2.0
더 많은 글 을 주목 하 세 요:
deepinmind

좋은 웹페이지 즐겨찾기