2016-09-24 14 views
0

오늘 나는 Visual VM 프로파일 링의 결과에 혼란스러워했습니다.VisualVM - 이상한 자체 시간

public class Encoder { 
    ... 
    private BitString encode(InputStream in, Map<Character, BitString> table) 
     throws IOException { 

    BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 

    BitString result = new BitString(); 
    int i; 
    while ((i = reader.read()) != -1) { 
     char ch = (char) i; 
     BitString string = table.get(ch); 
     result = result.append(string); 
    } 

    return result; 
    } 
} 

이 방법은, 스트림에서 문자를 읽고 한 번에 하나

나는 다음과 같은 간단한 자바 방법이있다. 각 문자에 대해 비트 스트링 표현을 조회하고 전체 비트 스트림을 나타 내기 위해이 비트 스트링을 결합합니다.

BitString은 기본 바이트 배열을 사용하여 일련의 비트를 나타내는 사용자 지정 데이터 구조입니다.

이 메서드는 매우 잘 수행되지 않습니다. 문제는 BitString#append입니다.이 메서드는 새 바이트 배열을 만들고 두 입력 BitString의 비트를 복사 한 다음 새 BitString 인스턴스로 반환합니다. 내가 무슨 일이 일어나고 있는지 확인하기 위해 VisualVM과를 사용하려고 할 때

public BitString append(BitString other) { 

    BitString result = new BitString(size + other.size); 
    int pos = 0; 

    for (byte b : this) { 
    result.set(pos, b); 
    pos++; 
    } 
    for (byte b : other) { 
    result.set(pos, b); 
    pos++; 
    } 

    return result; 
} 

그러나, 여기에 내가 가진 무엇 :

profiling

나는 일반적으로 약간의 비주얼 VM 경험과 프로파일이있다. 내 이해를 위해,이 문제는 encode 메서드 자체에 어딘가에 거짓말을 한 것처럼 보입니다. append이 아닙니다.

확인하려면,이 같은 전체 인코딩 방법 및 사용자 정의 시간 측정과 APPEND 호출 둘러싸인 :

public class Encoder { 
    private BitString encode(InputStream in, Map<Character, BitString> table) 
     throws IOException { 

>> long startTime = System.currentTimeMillis(); 
>> long appendDuration = 0; 

    BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 

    BitString result = new BitString(); 
    int i; 
>> long count = 0; 
    while ((i = reader.read()) != -1) { 
     char ch = (char) i; 
     BitString string = table.get(ch); 

>> long appendStartTime = System.currentTimeMillis(); 
     result = result.append(string); 
>> long appendEndTime = System.currentTimeMillis(); 
>> appendDuration += appendEndTime - appendStartTime; 

>> count++; 
>> if (count % 1000 == 0) { 
>>  log.info(">>> CHARACTERS PROCESSED: " + count); 
>>  long endTime = System.currentTimeMillis(); 
>>  log.info(">>> TOTAL ENCODE DURATION: " + (endTime - startTime) + " ms"); 
>>  log.info(">>> TOTAL APPEND DURATION: " + appendDuration + " ms"); 
>> } 
    } 

    return result; 
    } 
} 

을 그리고 나는 다음과 같은 결과를 얻었다 :

CHARACTERS PROCESSED: 102000 
TOTAL ENCODE DURATION: 188276 ms 
APPEND CALL DURATION: 188179 ms 

이에서 같다을 Visual VM의 결과와 모순됩니다.

무엇이 누락 되었습니까?

+0

어떻게 시간을 측정 했습니까? 코드를 추가 할 수도 있습니까? – hunter

+0

시간 측정 방법에 대한 설명과 '추가'코드를 추가했습니다. IO 나 네트워크가 기다리고 있다고 생각하지 않습니다. 어쩌면 GC 멈 춥니 다? –

+0

[* this method *] (http://stackoverflow.com/a/378024/23771)를 사용해 보셨습니까? Java와 잘 작동하며 시간이 어디로 가는지 정확하게 알려줍니다. * 측정하지 않습니다. 오히려 활동은 활동의 상당 부분을 정확히 찾아내는 데 활용됩니다. 그것을 사용하여 매우 거친 측정을 얻을 수 있지만 문제를 정확하게 발견 할 수 있습니다. –

답변

0

[본 답변은 유효하지 않습니다. 그러나 OP가 회원으로부터 도움을 얻을 때까지 나는 그것을 지킨다. 왜냐하면이 게시물에는 다른 사람들이 문제를 이해하는 데 도움이되는 두 개의 코멘트가 들어 있기 때문이다.]

이 경우 VisualVM은 실제 CPU 시간을 측정했지만 측정 한 시간 값은 "경과 시간"입니다.

실행 스레드가 IO 또는 네트워크를 대기해야하는 경우 해당 시간은 CPU 시간으로 측정되지 않습니다.

+0

내 확장 답변을 참조하십시오 - 나는'append' 구현을 포함 시켰습니다. 그곳에는 어떤 IO도 없다고 생각합니다. 어쩌면 오히려 GC가 일시 중지 되었습니까? 그러나 스크린 샷에서 볼 수 있듯이 Visual VM은 '시간'과 '시간 (CPU)'의 두 가지 값을 표시합니다. '시간'이 '경과 된 시간'이고 '시간 (CPU)'이 '실제 CPU 시간'입니까? –

+0

네, 맞습니다. 뭔가 이상합니다. 내 답변이 당신의 경우에 유효하지 않습니다. 2 엔코 드 호출의 경우 append가 4 번만 호출되었습니다.한눈에 모든 호출이 기록되지 않았습니다. VisuvalVM에 익숙한 사람이 귀하를 도울 수 있습니다. 나는 JProfiler에 대한 나의 경험을 바탕으로 당신을 도우려고했습니다. 감사 – hunter