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의 감속보다 나빠요. 그래서 저는 샘플링 프로파일 러가 현실과 너무 멀리 떨어져있는 것입니다. .
Runtime.freeMemory() 및 Runtime.totalMemory() 호출이 네이티브 호출 인 경우에도 성능은 시간 프로파일과 샘플 프로파일의 결과간에 여전히 일치하지 않습니다. 샘플 프로파일에서 모든 스택 추적의 80 % 이상을 소비합니다. 시간 프로파일에서 이러한 원시 메소드를 호출하는 함수는 총 시간의 80 % 근처에서 소비하지 않습니다. 필자는 두 가지 프로파일 링 방법이 어떻게 다른 결과를 초래할 수 있는지 이해하지 못합니다. – zelinka
타이머는 바이트 코드 삽입을 사용하여 메소드 시작 및 종료를 프로파일 링합니다. 메서드가 네이티브 인 경우 타이머 코드를 삽입 할 수 없습니다. –
샘플링 기반 프로파일 러에서 말하는 것과 프로그램의 런타임에서 말하는 것과는 큰 차이가 있지만 타이머 문제는 무시합니다. System.currentTimeMillis() 호출을 사용하여 무언가의 소요 시간에 대한 대략적인 아이디어를 얻었을 때 Runtime.freeMemory()에 대한 호출이 프로그램의 속도를 대략 2 배 느리게한다는 것을 분명히 알 수 있습니다. 샘플 프로파일 러를 보면 Runtime.freeMemory()를 제거하면 훨씬 더 빠른 속도 향상을 기대할 수 있습니다. – zelinka