我最近开始做最快速的应用程序。 方法很简单:
我将所有下载相同的不可压缩文件的多个线程实例化,然后我计算平均下载速度。
但我认为我有一些表演问题。当我使用多个线程开始测试时,我在logCat中看到了很多GC_CONCURRENT freed
和WAIT_FOR_CONCURRENT_GC
。
我不明白从哪里来的。
习惯上这些问题似乎出现在某些环境中,比如会造成太多的物体或巨大的物体,但我不认为这就是这种情况......
这是我的代码(简化 - 没有速度计算):
public class SpeedTest extends Activity{
private final int NB_THREADS = 2;
private long bytesIn;
private long downloadTime;
private List<Downloader> downloaders = new ArrayList<Downloader>();
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.speed_test);
bytesIn = 0;
for (int i = 0; i < NB_THREADS; i++){
downloaders.add(new Downloader());
downloaders.get(i).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, i);
}
}
private synchronized void addBytes(){ bytesIn++; }
private class Downloader extends AsyncTask<Integer, Void, Void>{
@Override
protected Void doInBackground(Integer... params){
Log.d("eduine", "Downloader " + params[0] + " started");
try{
InputStream stream = new URL("http://test-de-vitesse.ariase.com/ariasetool/1mb_random.bin").openConnection().getInputStream();
while((stream.skip(1)) != 0){
addBytes();
}
stream.close();
}catch (MalformedURLException e){
e.printStackTrace();
Log.e("eduine", "malformed url : " + e.getMessage());
}catch (IOException e){
e.printStackTrace();
Log.e("eduine", "io error : " + e.getMessage());
}
Log.d("eduine", "Downloader " + params[0] + " terminated");
return null;
}
}
}
所以我想知道是否有人已经遇到过这个问题,或者知道为什么会出现这些性能问题,因为它会影响速度计算。
提前致谢!
02-12 14:18:40.945: D/eduine(15637): Downloader 0 started
02-12 14:18:40.955: D/eduine(15637): Downloader 1 started
02-12 14:18:41.355: D/dalvikvm(15637): GC_CONCURRENT freed 3102K, 33% free 7552K/11240K, paused 3ms+3ms, total 20ms
02-12 14:18:41.395: D/dalvikvm(15637): GC_CONCURRENT freed 1564K, 33% free 7533K/11240K, paused 3ms+3ms, total 18ms
02-12 14:18:41.465: D/dalvikvm(15637): GC_CONCURRENT freed 1657K, 33% free 7537K/11240K, paused 2ms+7ms, total 20ms
02-12 14:18:41.465: D/dalvikvm(15637): WAIT_FOR_CONCURRENT_GC blocked 8ms
02-12 14:18:41.485: D/dalvikvm(15637): GC_CONCURRENT freed 1657K, 33% free 7541K/11240K, paused 2ms+3ms, total 17ms
02-12 14:18:41.485: D/dalvikvm(15637): WAIT_FOR_CONCURRENT_GC blocked 10ms
02-12 14:18:41.505: D/dalvikvm(15637): GC_CONCURRENT freed 1669K, 33% free 7533K/11240K, paused 3ms+1ms, total 17ms
02-12 14:18:41.505: D/dalvikvm(15637): WAIT_FOR_CONCURRENT_GC blocked 10ms
02-12 14:18:41.525: D/dalvikvm(15637): GC_CONCURRENT freed 1609K, 33% free 7537K/11240K, paused 3ms+3ms, total 16ms
02-12 14:18:41.545: D/dalvikvm(15637): GC_CONCURRENT freed 1669K, 34% free 7529K/11240K, paused 3ms+2ms, total 16ms
02-12 14:18:41.545: D/dalvikvm(15637): WAIT_FOR_CONCURRENT_GC blocked 13ms
等等...直到
02-12 14:21:14.795: D/dalvikvm(16164): GC_CONCURRENT freed 1537K, 33% free 7533K/11240K, paused 3ms+2ms, total 16ms
02-12 14:21:14.815: D/dalvikvm(16164): GC_CONCURRENT freed 1537K, 33% free 7533K/11240K, paused 2ms+2ms, total 15ms
02-12 14:21:14.835: D/dalvikvm(16164): GC_CONCURRENT freed 1537K, 33% free 7533K/11240K, paused 2ms+3ms, total 16ms
02-12 14:21:14.845: D/eduine(16164): Downloader 0 terminated at 1392211274859
02-12 14:21:14.855: D/dalvikvm(16164): GC_CONCURRENT freed 1545K, 34% free 7529K/11240K, paused 3ms+3ms, total 17ms
02-12 14:21:14.915: D/eduine(16164): Downloader 1 terminated at 1392211274925
编辑:使用ThreadPool的相同问题,代码如下。
public class SpeedTest extends Activity{
private final int NB_OF_THREADS = 8;
private long bytesIn;
private long start;
ExecutorService executorService = new ThreadPoolExecutor(NB_OF_THREADS, NB_OF_THREADS, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(NB_OF_THREADS, true), new ThreadPoolExecutor.CallerRunsPolicy());
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.speed_test);
bytesIn = 0;
start = System.currentTimeMillis();
for (int i = 0; i < NB_OF_THREADS; i++) executorService.submit(new Downloader(i));
}
private synchronized void addByte(){ bytesIn++; }
private class Downloader implements Runnable{
private int id;
private InputStream stream;
private long downloadTime;
public Downloader(int _id){ id = _id; }
@Override
public void run(){
Log.d("eduine", "Downloader " + id + " started at " + System.currentTimeMillis());
try{
HttpURLConnection connexion = (HttpURLConnection) new URL("http://test-de-vitesse.ariase.com/ariasetool/1mb_random.bin").openConnection();
connexion.setUseCaches(false);
stream = connexion.getInputStream();
while((stream.skip(1)) != 0) addByte();
stream.close();
downloadTime = (System.currentTimeMillis() - start);
downloadTime = downloadTime == 0 ? 1 : downloadTime;
}catch (MalformedURLException e){
e.printStackTrace();
Log.e("eduine", "malformed url : " + e.getMessage());
}catch (IOException e){
e.printStackTrace();
Log.e("eduine", "io error : " + e.getMessage());
}
Log.d("eduine", "Downloader " + id + " terminated at " + System.currentTimeMillis());
}
}
}
答案 0 :(得分:0)
线程对象本身为其堆栈消耗了大量内存。要从实例化/自由线程中清除测试,请不要使用AsyncTask(创建Thread),而是事先创建一个固定的线程池,开始测试,等待它结束,然后才关闭线程池。