2012-12-07 4 views
1

Runtime.freeMemory를 프로파일 링하는 코드가 있습니다. 내가 -Xrunhprof 사용하여 프로파일 러를 실행하면Runtime.freeMemory()를 호출하는 java 코드 프로파일 링

package misc; 
import java.util.ArrayList; 
import java.util.Random; 
public class FreeMemoryTest { 
private final ArrayList<Double> l; 
private final Random r; 
public FreeMemoryTest(){ 
    this.r = new Random(); 
    this.l = new ArrayList<Double>(); 
} 
public static boolean memoryCheck() { 
    double freeMem = Runtime.getRuntime().freeMemory(); 
    double totalMem = Runtime.getRuntime().totalMemory(); 
    double fptm = totalMem * 0.05; 
    boolean toReturn = fptm > freeMem; 
    return toReturn; 
} 
public void freeMemWorkout(int max){ 
    for(int i = 0; i < max; i++){ 
     memoryCheck(); 
     l.add(r.nextDouble()); 
    } 
} 
public void workout(int max){ 
    for(int i = 0; i < max; i++){ 
     l.add(r.nextDouble()); 
    } 
} 
public static void main(String[] args){ 
    FreeMemoryTest f = new FreeMemoryTest(); 
    int count = Integer.parseInt(args[1]); 
    long startTime = System.currentTimeMillis(); 
    if(args[0].equals("f")){ 
     f.freeMemWorkout(count); 
    } else { 
     f.workout(count); 
    } 
    long endTime = System.currentTimeMillis(); 
    System.out.println(endTime - startTime); 
} 
} 

: CPU = 샘플을, 통화의 대부분은 Runtime.freeMemory (에있는)이 같은 :

CPU SAMPLES BEGIN (total = 531) Fri Dec 7 00:17:20 2012 
rank self accum count trace method 
1 83.62% 83.62%  444 300274 java.lang.Runtime.freeMemory 
2 9.04% 92.66%  48 300276 java.lang.Runtime.totalMemory 

여기 내 코드입니다 내가 -Xrunhprof 사용하여 프로파일 실행하면 : CPU = 시간, 나는 전화의 전혀 Runtime.freeMemory에 표시되지 않습니다, 다음과 같이 상위 5 호출은 다음과 같습니다

CPU TIME (ms) BEGIN (total = 10042) Fri Dec 7 00:29:51 2012 
rank self accum count trace method 
1 13.39% 13.39% 200000 307547 java.util.Random.next 
2 9.69% 23.08%  1 307852 misc.FreeMemoryTest.freeMemWorkout 
3 7.41% 30.49% 100000 307544 misc.FreeMemoryTest.memoryCheck 
4 7.39% 37.88% 100000 307548 java.util.Random.nextDouble 
5 4.35% 42.23% 100000 307561 java.util.ArrayList.add 

이 두 프로파일은 너무하다 서로 다르다. 저는 샘플이 시간의 결과를 적어도 대략적으로 추정한다고 생각했지만, 여기에는 매우 근본적인 차이가 있습니다. 샘플의 80 % 이상을 소비하는 것은 시간 프로파일에도 나타나지 않습니다. 이것은 나에게 어떤 의미가되지 않습니다, 왜 이런 일이 일어나는지 알 수 있습니까? 이에

더 : freemem으로 실행

$ java -Xmx1000m -Xms1000m -jar memtest.jar a 20000000 5524 
//does not have the calls to Runtime.freeMemory() 
$ java -Xmx1000m -Xms1000m -jar memtest.jar f 20000000 9442 
//has the calls to Runtime.freeMemory() 

그것없이 실행으로 약 시간의 두 배를 필요로한다. CPU 시간의 80 %가 java.Runtime.freeMemory()에서 소비되고 그 호출을 제거하면 프로그램이 약 5 배속으로 향상 될 것으로 예상됩니다. 위에서 볼 수 있듯이 프로그램은 대략 2의 팩터입니다.

5의 감속도는 경험적으로 관찰 된 2의 감속보다 나빠요. 그래서 저는 샘플링 프로파일 러가 현실과 너무 멀리 떨어져있는 것입니다. .

답변

0

런타임 freeMemory() 및 totalMemory()는 기본 호출입니다.

는 타이머를 시간이 없습니다 http://www.docjar.com/html/api/java/lang/Runtime.java.html

참조하지만, 샘플러 수 있습니다.

+0

Runtime.freeMemory() 및 Runtime.totalMemory() 호출이 네이티브 호출 인 경우에도 성능은 시간 프로파일과 샘플 프로파일의 결과간에 여전히 일치하지 않습니다. 샘플 프로파일에서 모든 스택 추적의 80 % 이상을 소비합니다. 시간 프로파일에서 이러한 원시 메소드를 호출하는 함수는 총 시간의 80 % 근처에서 소비하지 않습니다. 필자는 두 가지 프로파일 링 방법이 어떻게 다른 결과를 초래할 수 있는지 이해하지 못합니다. – zelinka

+0

타이머는 바이트 코드 삽입을 사용하여 메소드 시작 및 종료를 프로파일 링합니다. 메서드가 네이티브 인 경우 타이머 코드를 삽입 할 수 없습니다. –

+0

샘플링 기반 프로파일 러에서 말하는 것과 프로그램의 런타임에서 말하는 것과는 큰 차이가 있지만 타이머 문제는 무시합니다. System.currentTimeMillis() 호출을 사용하여 무언가의 소요 시간에 대한 대략적인 아이디어를 얻었을 때 Runtime.freeMemory()에 대한 호출이 프로그램의 속도를 대략 2 배 느리게한다는 것을 분명히 알 수 있습니다. 샘플 프로파일 러를 보면 Runtime.freeMemory()를 제거하면 훨씬 더 빠른 속도 향상을 기대할 수 있습니다. – zelinka