2014-06-07 1 views
-2

자바 다운로더를 만들고 내 wampserver에서 900MB 파일을 다운로드하면 올바르게 작동하지만 램 사용량을 확인하면 그만큼 늘어납니다. 그 이유는 무엇입니까? IDM을 사용하여 동일한 파일 형식을 내 wampserver에 다운로드했는데 많은 램을 사용하지 않았습니다 프로세스 및 디스크 사용량이 약 50MB 및 5 % 컵 인 자바 다운로더를 볼 때 성능 탭에서 성능을 볼 때 RAM이 많이 증가합니다. http://i.stack.imgur.com/zfxNv.pngwampserver에서 java로 파일 다운로드

내 응용 프로그램이 동시에이 파일을 다운로드 8 스레드를 만들이 내 코드 :

private void downloadFile() { 
    try { 
     this.response = this.con.getInputStream(); 
     this.bis = new BufferedInputStream(this.response, 32 * 1024); 
       this.responseContentSize = this.con.getContentLength(); 


     if (this.responseContentSize == (this.end_range - this.start_range) + 1) { 

         int MAX_BUFFER_SIZE = 32*1024; 
      byte buffer[] = new byte[MAX_BUFFER_SIZE]; 
      makeTmpFile(); 
      out = new FileOutputStream(this.tmpdir + this.tmpFilename); 
      bos = new BufferedOutputStream(out, 32 * 1024); 

      while (true) { 

       int r = this.bis.read(buffer, 0, this.MAX_BUFFER_SIZE); 
       if (r == -1) 
        break; 

       bos.write(buffer, 0, r); 
       downloadedBytes += r; 

      } 

      if (bos != null) 
       bos.close(); 
      if (out != null) 
       out.close(); 
      if (bis != null) 
       bis.close(); 
      if (response != null) 
       response.close(); 

     } 
    } catch (IOException e) { 
     sharedDownloadStatus.setCell(this.threadIndex, STATUS, 0);//error 
     log.setLog("func : downloadFile =>\n couldnt download file\n" + e.getMessage()); 
    } 

} 

답변

0

당신은 각 청크에 대한 데이터 버퍼를 할당

이 성능 그림입니다. 그들은 가비지 컬렉터가 일시적으로 많은 양의 메모리를 차지합니다.

스레드 당 하나의 데이터 버퍼 만 보유하십시오. (예를 들어, ThreadLocal 사용).

+0

내 코드의 일부를, 무슨 뜻? 내 버퍼 배열이 while 루프 밖에 있기 때문에 – wineo

+0

이 스 니펫이주기 자체에서 실행되지 않습니까? 당신은 8 스레드 언급. – Basilevs

+0

ok 8thread의 크기가 32KB 인 8 버퍼를 8 * 32KB로 사용하므로 많은 양의 RAM이 필요하지 않으므로 왜 그렇게 많이 차지합니까? 나는 너의 의미를 이해하지 못 하느냐? 죄송합니다. 제게 설명해주십시오. – wineo

0

jvisualvm.exe 프로그램을 사용하면 메모리 소비를 확인하고 할당 된 부분을 볼 수 있습니다. jvisualvm은 jdk 설치의 bin 폴더에 있습니다.

는 Heres는 내가 코드를 변경 어떻게 할 것인지 :

  • 이 BufferedInput/BufferedOutput 없애 스트림. 이러한 버퍼링 된 스트림은 프로그램에서 불필요하며 추가 메모리 할당 (버퍼링 된 스트림 당 32kb)을 추가하는 것일 뿐이지 만 필요하지는 않습니다.

  • 8 개의 스레드를 사용하지 마십시오. 네트워크를 통해 매우 큰 파일을 전송할 수있는 파일 다운로드 응용 프로그램을 작성했으며 최적의 스레드 수는 2 또는 3입니다. 따라서 인터넷 연결보다 파일을 더 빠르게 다운로드 할 수 없습니다 여분의 스레드에서 아무것도하지만 메모리와 시간을 낭비하지 않습니다.

  • 작은 버퍼를 사용하십시오. 32kb 버퍼가 상당히 큽니다. 1kb와 같은 더 작은 버퍼를 사용하여 테스트 할 것입니다.

  • Java 응용 프로그램 메모리/CPU 사용량과 함께 wammp memory/cpu 사용을 혼동하지 마십시오. 성능 탭 대신 Windows 작업 관리자의 '프로세스'탭을 사용하십시오.

그게 내가 당신의 전체 프로그램을 가질 수는 없지만 테스트와 디버깅 성능은 당신에게 달렸지 만 이것들은 내가 할 일이라고 말했습니다. 아래는 가능한 한 많이 수정 한 코드입니다.


private void downloadFile() { 
    try { 
     this.response = this.con.getInputStream(); 
     this.responseContentSize = this.con.getContentLength(); 


     if (this.responseContentSize == (this.end_range - this.start_range) + 1) { 

      int MAX_BUFFER_SIZE = 1024; 
      byte buffer[] = new byte[MAX_BUFFER_SIZE]; 
      makeTmpFile(); 
      out = new FileOutputStream(this.tmpdir + this.tmpFilename); 

      int r = 0; 
      while ((r = response.read(buffer)) != -1) { 
       out.write(buffer, 0, r); 
       downloadedBytes = r; 

      } 
     } 
    } catch (IOException e) { 
     sharedDownloadStatus.setCell(this.threadIndex, STATUS, 0);//error 
     log.setLog("func : downloadFile =>\n couldnt download file\n" + e.getMessage()); 
    } finally { 
     if (out != null) 
      out.close(); 
     if (response != null) 
      response.close(); 
    } 

} 
+0

유익한 응답을 주셔서 감사합니다. 덕분에 도움이되었지만, 왜 IDM 다운로드 관리자가 다운로드 용으로 8 스레드를 만들고, 많은 메모리를 소비하지 않았습니까? – wineo

+0

@wineo IDM 다운로더가 8을 사용함을 어떻게 알 수 있습니까? 또한 최대 8 개까지 사용할 수 있으며 항상 그렇지는 않습니다. 8. 초고속 컴퓨터와 인터넷을 사용하는 경우 고려하십시오. 이 경우 상황에 따라 8 개의 스레드가 최적 일 수 있습니다.이제 오래된 56k 연결을 고려해보십시오. 8 개의 스레드가 초당 56kb의 속도를 낼 수 있다고 생각합니까? ... 아마도 그렇지 않습니다. 또한 추가 진단을 원한다면 jvisualvm 통계를 프로그램에 게시 할 것인지 물어볼 것입니다. 현재 귀하의 게시물에 따라 귀하의 메모리 드레인이 어디서 왔는지는 알 수 없습니다 ... 우리는 그 웨이퍼를 알고 있습니다. –

+0

그리고 내 이메일에 다운로더 프로젝트를 이메일로 보낼 수 있습니까?> mr [점] jahankhah [at] yahoo [dot ] com? – wineo