2014-02-12 2 views
1

최근에 가장 빠른 애플리케이션을 시작했습니다. 이 방법은 간단합니다 :Android MultiThread SpeedTest에 성능 문제가 있습니다.

같은 압축 할 수없는 파일을 모두 다운로드하는 여러 스레드를 인스턴스화 한 다음 평균 다운로드 속도를 계산합니다.

하지만 성능 문제가 있습니다. 두 개 이상의 스레드로 테스트를 시작하면 logCat에 GC_CONCURRENT freedWAIT_FOR_CONCURRENT_GC이 많이 표시됩니다. 나는 그것이 어디에서 왔는지 이해하지 못한다. 속도없이 - 여기

단순화 내 코드입니다 (...

습관적으로 이러한 문제는 너무 많은 개체 또는 거대한 물체를 instanciating 같은 특정 circumpstances에 표시 할 것 같다,하지만 난 그 사건은 여기서 생각하지 않는다 계산) : 그것은 속도 계산을 왜곡하기 때문에

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; 
     } 
    } 
} 

그래서 내가 좋아하는 것은, 누군가가 이미이 문제가 발생 알고, 또는 본 공연의 문제가 왜 어떤 생각을 가지고 있습니다.

미리 감사드립니다.


편집 : LogCat을 게시하는 것을 잊었습니다. 죄송합니다. ThreadPool이를 사용하여 같은 문제 아래 코드 :

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 

까지.

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

스레드 개체 자체는 스택에 많은 메모리를 사용합니다. 인스턴스화/프리 스레드에서 테스트를 정리하려면 AsyncTask (스레드 생성)를 사용하지 말고 사전에 고정 된 스레드 풀을 생성하고 테스트를 시작하고 종료 될 때까지 기다린 다음 스레드 풀만 종료하십시오.

+0

ThreadPool을 사용해도 동일한 문제가 발생합니다. 위의 코드를 게시하려면보고 싶습니다. – eduine

+0

대용량 메모리 할당 - 삭제가 다른 곳에서 발생하는 것처럼 보입니다. 최소한의 프로그램을 만들어 Android에서 실행하십시오. 더 작은 프로그램을 만들고 gc 로그온으로 데스크탑에서 실행하십시오. –

+0

나는 마침내 오류를 발견했다. 효과적으로 할당 문제가 있었는데, 나는 나의 루프에 바이트 []를 재 할당했다. 그래서 엄청난 양의 메모리가이 방법으로 사용되었다. 고맙습니다. – eduine