我有一些代碼,配置文件Runtime.freeMemory。這裏是我的代碼:分析調用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);
}
}
當我使用-Xrunhprof運行分析器: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,並且前五名電話如下:
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%樣本的東西甚至不會出現在時間輪廓中。這對我來說沒有任何意義,有人知道爲什麼會發生這種情況嗎?
更多這方面的:
$ 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()
與freemem在運行需要的時間大致兩倍因爲沒有它運行。如果在java.Runtime.freeMemory()中花費了80%的CPU時間,並且刪除了該調用,則我預計該程序的加速速度大約爲5.如上所述,程序加速因子大約爲2.
因子5的減速比經驗觀察到的因子2的減慢要差,所以我不明白的是採樣分析器如何遠離現實。
即使對Runtime.freeMemory()和Runtime.totalMemory()的調用是本地調用,它們在時間配置文件和樣本配置文件的結果之間的性能仍然不一致。在樣本配置文件中,它們消耗了所有堆棧軌跡的80%以上。在時間配置文件中,調用這些本機方法的函數不會佔用總時間的80%左右。我不明白這兩種分析方法如何導致這種不同的結果。 – zelinka
定時器使用字節碼注入來剖析方法的開始和結束。如果該方法是本地的,它不能注入計時器代碼。 –
忽略計時器問題,儘管基於採樣的分析器說的內容與程序的運行時間表示之間仍存在很大差異。使用System.currentTimeMillis()調用粗略瞭解某些事情需要花費的時間,我們可以清楚地看到對Runtime.freeMemory()的調用減慢了大約2倍。查看樣本分析器,我會期望消除Runtime.freeMemory()會導致更大的加速,這是我們看不到的。 – zelinka