2008-09-16 3 views
1

HP-UX 환경에서 특정 Java 응용 프로그램과 관련하여 특이한 문제가 발생했습니다.HP-UX 환경 JVM에서 C 힙과 Java 힙의 실행 범위는 무엇입니까?

힙이 -mx512로 설정되어 있지만 gpm을 사용하여이 Java 프로세스의 메모리 영역을 보면 RSS 영역이 1.6GB 이상이고 DATA 영역에 1.1GB가 할당 된 것을 보여줍니다. 24-48 시간에 걸쳐 매우 빠르게 성장한 다음 몇 시간마다 2MB의 속도로 계속 성장합니다. 그러나 Java 힙은 누출의 흔적을 보이지 않습니다.

이 내가 조금 연구 및 자바 힙 및 C 힙 메모리 누수에이 HP 쓰기 업을 찾을 수 얼마나 호기심 : 자바 대 C 힙에서 실행 될지 결정 어떤 http://docs.hp.com/en/JAVAPERFTUNE/Memory-Management.pdf

내 질문입니다 힙 및 Java 힙을 통해 실행되지 않는 항목의 경우 C 힙에서 실행되는 해당 오브젝트를 어떻게 식별 할 수 있습니까? 또한 Java 힙 C 힙 안에 앉아 있습니까?

답변

0

당신이 주어진 숫자로 추측하는 것은 Java VM의 메모리 누수입니다. 참조한 용지에 나열된 다른 VM 중 하나를 사용해 볼 수도 있습니다. 또 다른 (훨씬 어려운) 대안은 HP 플랫폼에서 열린 Java를 컴파일하는 것일 수 있습니다.

Sun의 Java는 아직 100 % 오픈되어 있지 않으며, 아직 개발 중입니다.하지만 나는 sourceforge에 하나 있다고 생각합니다.

Java는 또한 메모리를 방해합니다. 때로는 OS 메모리 관리를 조금 혼란스럽게합니다. (Windows에서 메모리가 부족 해지고 Java가 일부를 해제하도록 요청할 때 Java가 모든 객체를 터치하여 스왑 파일에서로드되고 Windows가 고뇌하고 죽는 것처럼 비명을 지른다.) 나는 그것이 당신이보고있는 것이라고 생각하지 않습니다.

2

일반적으로 Java 객체의 데이터 만 Java 힙에 저장되고 Java VM에 필요한 다른 모든 메모리는 "원시"또는 "C"힙에서 할당됩니다 (실제로 Java 힙 자체는 C 힙에서 할당 된 하나의 인접한 청크).

연속 가비지로 JVM에서 Java 힙 (또는 세대 별 가비지 수집이 사용중인 경우 힙)이 필요하므로 일반적으로 최대 힙 크기 (-mx 값)는 JVM 시작 시간에 할당됩니다. 실제로, Java VM은이 공간의 사용을 최소화하려고 노력합니다. 따라서 운영 체제는 실제 메모리를 예약 할 필요가 없습니다 (운영 체제는 저장소의 작성시기를 알기에 충분하지 않습니다) .

따라서 Java 힙은 메모리에서 일정한 공간을 차지합니다.

나머지 저장소는 Java VM 및 사용중인 JNI 코드에서 사용됩니다. 예를 들어 JVM은로드 된 클래스의 Java 바이트 코드 및 상수 풀, JIT 컴파일 코드 결과, JIT 코드 컴파일 작업 영역, 원시 스레드 스택 및 기타 이러한 잡화를 저장하는 메모리가 필요합니다.

JNI 코드는 "고유"방식의 형태로 Java 객체에 바인딩 될 수있는 플랫폼 전용 (컴파일 된) C 코드입니다. 이 메소드가 실행되면 바운드 코드가 실행되고 C 힙의 메모리를 소비하는 표준 C 루틴 (예 : malloc)을 사용하여 메모리를 할당 할 수 있습니다.

4

Java 프로세스를 구성하는 요소를 고려하십시오.

당신은이 :

  • 는 JVM (C 프로그램)
  • JNI 데이터를
  • 자바 바이트 코드
  • Java 데이터
  • 특히

, 그들은 모두 C에 살고 힙 (JVM 힙은 자연스럽게 C 힙의 일부 임).

Java 힙에서 Java 힙은 Java 바이트 코드 및 Java 데이터입니다. 그러나 Java 힙에는 "여유 공간"도 있습니다.

일반적인 (즉 Sun) JVM은 필요에 따라 Java 힙만 커지 만 축소하지는 않습니다. 정의 된 최대 값 (-Xmx512M)에 도달하면 성장을 멈추고 남아있는 것이 무엇이든 처리합니다. 최대 힙이 모두 소모되면 OutOfMemory 예외가 발생합니다.

Xmx512M 옵션이 수행하지 않는 것은 프로세스의 전체 크기를 제한하는 것입니다. 프로세스의 Java 힙 부분 만 제한합니다.

예를 들어 10MB의 Java 힙을 사용하지만 500MB의 C 힙을 할당하는 JNI 호출을 호출하는 고안된 Java 프로그램을 사용할 수 있습니다. Java 힙 크기가 작더라도 프로세스 크기가 얼마나 큰지 알 수 있습니다. 또한 새로운 NIO 라이브러리를 사용하면 힙 외부에서도 메모리를 연결할 수 있습니다.

Java GC가 일반적으로 "콜렉터 복사 중"이라는 점을 고려해야합니다. 즉, 수집중인 메모리에서 "실제"데이터를 가져와 다른 메모리 섹션에 복사한다는 의미입니다. 적어도 Xmx 매개 변수의 관점이 아닌 HEAP의 일부가 아닌이 빈 공간. 그것은 마치 "새로운 힙"과 같으며 복사 후에는 힙의 일부가됩니다 (이전 GC가 다음 공간으로 사용됨). 512MB 힙을 가지고 있고 510MB에 있다면 Java는 라이브 데이터를 어느 곳에서나 복사 할 것입니다. 순진한 생각은 다른 큰 열린 공간 (500 + MB와 같은)에있을 것입니다. 귀하의 모든 데이터가 "살아"있다면, 복사 할 수있는 큰 덩어리가 필요합니다.

따라서 극단적 인 경우에는 특정 힙 크기를 처리하기 위해 시스템의 여유 메모리를 두 배로 늘려야합니다. 512MB 힙의 경우 최소 1GB.

실제로는 그렇지 않으며 메모리 할당 등은 그보다 복잡하지만 힙 복사본을 처리하기 위해서는 많은 양의 여유 메모리가 필요하므로 전체 프로세스 크기에 영향을 미칩니다.

마지막으로, JVM은 rt.jar 클래스에서 시작을 쉽게하기 위해 VM에 매핑하는 것과 같은 일을 즐깁니다. 그것들은 읽기 전용 블록으로 매핑되고 다른 자바 프로세스에서 공유 될 수 있습니다. 이러한 공유 페이지는 실제 메모리 (가상 메모리의 마술)를 한 번만 소비하더라도 모든 Java 프로세스에 "계산"됩니다.

이제 프로세스가 계속 커지는 이유에 대해 Java OOM 메시지를 전혀 알지 못하면 누수가 Java 힙에 있지 않다는 것을 의미합니다. 그렇다고해서 다른 것 JRE 런타임, 타사 JNI 라이브러리, 원시 JDBC 드라이버 등).

관련 문제