"온 힙"과 "오프 힙"의 차이점


답변:


169

온 힙 저장소는 Java 힙에 존재하며 GC에 종속되는 오브젝트를 나타냅니다. 반면에 힙 외부 저장소는 EHCache에서 관리하지만 힙 외부에 저장되며 (GC의 영향을받지 않는) (직렬화 된) 개체를 나타냅니다. 오프 힙 저장소는 메모리에서 계속 관리되므로 온 힙 저장소보다 약간 느리지 만 디스크 저장소보다 여전히 빠릅니다.

힙 오프 스토어의 관리 및 사용과 관련된 내부 세부 사항은 질문에 게시 된 링크에서 잘 드러나지 않으므로 오프 디스크를 관리하는 데 사용되는 Terracotta BigMemory 의 세부 정보를 확인하는 것이 좋습니다. 저장. BigMemory (오프 힙 저장소)는 수 메가 바이트 또는 기가 바이트 인 힙에서 GC의 오버 헤드를 피하기 위해 사용됩니다. BigMemory는 다른 기본 Java 오브젝트와 달리 GC에 종속되지 않는 직접 ByteBuffer 를 통해 JVM 프로세스의 메모리 주소 공간을 사용 합니다.


18
추가 탐색을 위해 직접 ByteBuffer를 언급 한 경우 +1;)
Max

3
Direct ByteBuffer는 관리되지 않는 메모리에 대한 액세스를 제공하지만 GC의 대상이되는 데이터와는 달리 GC의 영향을받습니다. 이것은 GC에 의해 직접 ByteBuffer (MMap 종류가 아닌 ByteBuffer.allocateDirect 종류)가 수집되고 수집 될 때 Deallocater가 트리거되어 관리되지 않는 메모리도 효과적으로 수집하기 때문에 중요합니다.
Nitsan Wakart

Unsafe를 사용하여 객체를 할당하면 Onheap / DirectByteBuffers / ByteBuffers보다 읽기 및 쓰기 성능이 크게 향상되는 것처럼 보입니다. ashkrit.blogspot.com/2013/07/…
Joe C

98

에서 http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff

힙 오프로드 란 무엇입니까?

일반적으로 할당하는 모든 비 임시 객체는 java의 가비지 수집기에 의해 관리됩니다. VM은 가비지 수집을 수행하는 적절한 작업을 수행하지만 특정 시점에서 VM은 소위 'Full GC'를 수행해야합니다. 전체 GC에는 할당 된 전체 힙을 스캔하는 것이 포함됩니다. 즉, GC 일시 정지 / 느려짐은 애플리케이션 힙 크기에 비례합니다. 따라서 '메모리가 저렴합니다'라고 말하는 사람을 믿지 마십시오. Java 메모리 소비에서 성능이 저하됩니다. 또한 1GB 이상의 힙 크기를 사용하면 현저한 일시 중지가 발생할 수 있습니다. 거의 실시간에 가까운 작업을 수행하는 경우 클러스터 또는 그리드에서 Java 프로세스가 응답하지 않고 클러스터에서 삭제 될 수 있습니다.

그러나 오늘날의 서버 응용 프로그램 (부서 운 프레임 워크 ;-)에 자주 구축 됨)에는 4Gb를 훨씬 넘어서는 힙이 필요합니다.

이러한 메모리 요구 사항에 대한 한 가지 해결책은 객체의 일부를 비 Java 힙 (OS에서 직접 할당)으로 '오프로드'하는 것입니다. 다행스럽게도 java.nio는 '관리되지 않은'메모리 덩어리 (메모리 매핑 된 파일도 포함)를 직접 할당 / 읽고 쓰는 클래스를 제공합니다.

따라서 많은 양의 '관리되지 않은'메모리를 할당하고이를 사용하여 객체를 저장할 수 있습니다. 임의의 개체를 관리되지 않는 메모리에 저장하기 위해 가장 실용적인 해결책은 직렬화를 사용하는 것입니다. 즉, 응용 프로그램에서 개체를 오프 헤드 메모리로 직렬화하고 나중에 직렬화 해제를 사용하여 개체를 읽을 수 있습니다.

Java VM에서 관리하는 힙 크기를 작게 유지할 수 있으므로 GC 일시 중지가 밀리 초 내에 이루어지며 모두가 행복하고 일을 마칩니다.

이러한 오프 힙 버퍼의 성능은 대부분 직렬화 구현의 성능에 달려 있음이 분명합니다. 좋은 소식 : 어떤 이유로 FST 직렬화는 매우 빠릅니다 :-).

샘플 사용 시나리오 :

  • 서버 응용 프로그램의 세션 캐시 메모리 맵핑 파일을 사용하여 기가 바이트 (비활성) 사용자 세션을 저장하십시오. 사용자가 응용 프로그램에 로그인하면 데이터베이스를 처리하지 않고도 사용자 관련 데이터에 빠르게 액세스 할 수 있습니다.
  • 계산 결과 캐싱 (쿼리, html 페이지, ..) (c가 결과 개체를 직렬화 해제하는 것보다 계산이 느린 경우에만 해당)
  • 메모리 매핑 파일을 사용한 매우 간단하고 빠른 지속성

편집 : 일부 시나리오의 경우 더 큰 힙을 지원하기 위해 ConcurrentMarkAndSweep 또는 G1과 같은보다 정교한 가비지 수집 알고리즘을 선택할 수 있습니다 (그러나 16GB 힙을 초과하는 한계도 있음). 개선 된 '일시 정지되지 않은'GC (Azul)가있는 상용 JVM도 있습니다.


4
"다량의 '관리되지 않은'메모리를 할당하고이를 사용하여 오브젝트를 저장하십시오"-오브젝트 오프 헤드를 저장할 수 없습니다. 프리미티브를 저장할 수 있고 원하는 라이브러리에 래핑 할 수 있지만 객체는 아닙니다. 오프 힙으로 배치 한 데이터에는 객체 헤더가 없으며 동기화 할 수 없으며 다른 객체의 참조 필드로 참조 할 수 없습니다.
Nitsan Wakart

41

힙은 동적으로 할당 된 객체가있는 메모리의 장소입니다. 사용한 경우 new힙에 있습니다. 그것은 함수 스택이 존재하는 스택 공간과 반대입니다. 로컬 변수가 있으면 해당 참조가 스택에 있습니다. Java의 힙은 가비지 콜렉션의 대상이되며 오브젝트를 직접 사용할 수 있습니다.

EHCache의 힙이없는 스토리지는 일반 오브젝트를 힙에서 가져 와서 직렬화하여 EHCache가 관리하는 메모리 덩어리에 바이트로 저장합니다. 디스크에 저장하는 것과 같지만 여전히 RAM에 있습니다. 이 상태에서는 개체를 직접 사용할 수 없으므로 먼저 역 직렬화해야합니다. 가비지 수집 대상이 아닙니다.


단순히 힙에 있지는 않지만 직렬화 된 형식입니까?
Pacerier

1
그것이 어떻게 더 효율적입니까?
Pacerier

2
많은 방법이 있습니다. 오브젝트는 더 이상 기본 Java 힙에 없으므로 가비지 콜렉터의 시간을 낭비하지 않으며 JVM의 힙을 조각화하지 않으며 더 많이 사용되는 다른 오브젝트를위한 공간을 확보합니다. 또한 직렬화되어 있으며 곧 필요하지 않을 수도 있으므로 압축하거나 필요에 따라 이동하거나 디스크로 페이징 할 수도 있습니다.
Adam

1
핫스팟에서 GC 일시 정지 시간은 힙 크기에 직접적으로 의존합니다. BigMemory는 힙 대신 RAM을 사용하여 GC 일시 중지를 최소화하고 디스크 액세스의 IO 비용을 피함으로써 이러한 절충안을 제공합니다.
Chander Shivdasani


1

JVM은 힙이없는 메모리에 대해 아무것도 모릅니다. Ehcache는 디스크 내 캐시와 메모리 내 캐시를 구현합니다.


1

100 %가 아님; 그러나 힙은 코드 자체의 기능이나 Java 자체 또는 ehcache 자체의 기능과 같은 기능으로 내장 된 객체 또는 할당 된 공간 세트 (RAM)처럼 들립니다. 잘; 그러나 이것은 구성되지 않았기 때문에 1 배 느리게 들립니다. 즉, 힙을 사용하지 않고 (1 개의 긴 램 공간 세트를 의미 함) 대신 다른 주소 공간을 사용하여 약간 덜 효율적일 수 있습니다.

물론 다음 단계는 하드 드라이브 공간 자체입니다.

나는 ehcache를 사용하지 않기 때문에 당신은 저를 믿기를 원하지 않을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.