2011-08-28 7 views
17

아래에 언급 된 코드 (netbeans 사용)를 실행할 때 할당 된 힙 크기는 톱니 모양으로 다릅니다. 사용 된 힙 그래프를 톱니 모양으로 표시하는 jVisualVM의 캡처를 첨부합니다.이 프로그램은 간단한 무한 루프 인쇄입니다 "lol"n stdout.왜 톱니 모양의 그래프입니까?

class one{ 
    static int i=0; 
    public static void main(String a[]){ 
     while(i<10){ 
      System.out.println("lol"); 
     } 
    } 
} 

enter image description here 는 사람이 사용 된 힙의 그래프의 모양 뒤에 이유를 설명 할 수 있습니까?

PS : 나는 그것을 다소 넷빈즈 관련되지 않도록 넷빈즈를 사용하지 않고 실행하는 경우에도 이런 일이 ...

+1

그리고 좋은 ... 어 ... 3 메가 바이트에 의해 다를 것? 그게 사실 일 수 있습니까? – Owen

+0

다른 가비지 컬렉터 알고리즘을 시도하여 이에 대한 통찰력을 얻을 수 있습니다. 정보는 여기를 참조하십시오 : http://www.tikalk.com/java/garbage-collection-serial-vs-parallel-vs-concurrent-mark-sweep – skaffman

+3

@ buch11 : 가장 간단한 Java에서도 쓰레기의 엄청난 양을 과소 평가하지 마십시오. 메소드/API가 생성 할 수 있습니다. 나는 자바를 사용하여 멀티 스레드 과학 계산을 해왔고 재미있는 게 너무 많다고 말할 수 있습니다;) 대부분의 자바 프로그래머는 * Map *과 같은 것들을 행복하게 사용할 것입니다. 병목 현상이 아니면 문제가 없다는 것입니다. Java는 기본적으로 거의 모든 사람들이 무수히 많은 낭비를 일으키고 생각하는 세계입니다. * "쓰레기 수거가 처리됩니다"*. Photoshop이 Java로 작성되지 않은 이유가 있습니다.) – SyntaxT3rr0r

답변

23

힙 사용의 톱니 패턴은 System.out.println 호출 호출 중에 여러 로컬 변수가 작성된다는 사실로 설명 할 수 있습니다.

Visual VM - Memory snapshot

흥미로운 비트의 수에 다음 스냅 샷에 언급 한 바와 같이 가장 두드러진는 오라클/썬 JRE에, HeapCharBuffer 여러 인스턴스는 VisualVM과의 메모리 프로파일 러를 사용하여 얻은, 젊은 세대에 생성됩니다 힙에있는 활성 객체. 톱니 패턴은 에덴 공간이 채워질 때 발생하는 젊은 세대 가비지 수집주기에서 비롯됩니다. 프로그램에서 수행되는 무거운 연산 활동이 없기 때문에 JVM은 루프의 여러 반복을 실행할 수 있으므로 에덴 공간 (4MB 크기)이 채워집니다.계속되는 젊은 세대의 수집 사이클은 쓰레기 대부분을 제거합니다. 톱니 패턴의 동작은 이렇게 설명 할 수있다

Visual VM GC probes

: 객체가 아직 사용하지 않는 한 VisualVM과에서 얻은 다음 GC 추적에 의해 표시로는 거의 항상 에덴 공간의 전체입니다 에덴 공간을 채우는 일련의 객체 배분이 젊은 세대의 쓰레기 수거 사이클을 촉발시킨다. 이 프로세스는 기본 JVM 프로세스가 다른 프로세스에 의해 선점되지 않으므로 지연없이 주기적으로 반복되며 오브젝트 할당을 담당하는 JVM의 기본 스레드는 다른 스레드에 의해 선점되지 않습니다.

+0

요점을 찾았습니다 !!! 감사. – buch11

+0

당신을 진심으로 환영합니다. Btw, VisualVM과 Eclipse 사이에서 Alt 키를 누른 상태에서 완벽한 톱니파를 얻지 못했습니다. 반면에 스크린 샷은 VisualVM을 실행 한 적이 있다는 것을 나타냅니다. –

+0

실제로 쓰레드를 사용하는 프로그래밍을하고 있었는데 갑자기 코드가 무한한 loo에 들어갔다. JVisualVM으로 가서 쓰레드가 실행 중인지/잠자고/기다리는지를 확인했다. 톱니가 나 앞에서왔다. 그것이 스레드와 관련된 것이라고 생각했지만 위의 코드를 실행 해 보았습니다. 모든 퍼즐은 거기서 시작되었습니다 ... 예. 제 VisualVM이 항상 실행 중이었습니다. – buch11

1

는 오는 될 수있는 장소가 많이있다, 그것은 의존 가능성이 구현입니다. 다음 적어도 가능하다 (그러나 모두 단순히 추측이다)

  • 어딘가에서 System.out.println 하부 스트림의 스택에 소정의 바이트 배열 할당 (있다는 것을 출력 스트림의 기본적인 방법 중 하나 이다 쓰기 (바이트 [] B, 오프 int로 INT 렌))

  • 이 오버 헤드를 사용하고있는 모니터링 소프트웨어 (나는 그것을 사용하지 않는 한)

  • 이는 넷빈즈에서 오버 헤드 VM의에 의해 사용되는 출력이 끝나는 곳

5

정기적으로 객체를 할당하는 프로세스는 힙 메모리 소비가 꾸준히 증가하고 가비지 컬렉터가 더 이상 사용되지 않는 객체를 수집 할 때 즉각적으로 떨어지게되어 그 톱니 모양이됩니다.

System.out에 쓰는 동안 Java 프로세스가 할당 메모리를 유지하는 이유가 궁금한 경우 다른 스레드 (예 : JVisualVM에 현재 메모리 통계를 제공하는 스레드)가 메모리를 할당하는 스레드 일 수 있습니다.

1

실제로 jVisualVM이 추가 개체 할당을 유발합니다. jVisualVM 및 jconsole은 Java Management Extensions를 사용하고 있습니다. 실행중인 응용 프로그램에 연결하고 추가 객체가 생성되도록 JVM 메트릭을 요청합니다. 당신은 JVM 힙에서 사용 가능한 메모리를보고

Runtime.getRuntime().freeMemory() 

에 프로그램 호출에 추가하여이를 확인할 수 있습니다. 코드를 실행하면 메모리가 거의 변경되지 않지만 jVisualVM을 프로그램에 연결하면 메모리 사용량이 증가합니다.