2009-10-10 6 views
7

많은 스레드가 정확히 동일한 파일 (크기가 1GB 이상)을 읽고이를 입력 스트림으로 표시해야하는 Java 다중 스레드 응용 프로그램의 효율적인 방법은 무엇입니까? 나는 많은 스레드 (> 32)가있는 경우 시스템이 I/O를 경유하기 시작하고 많은 I/O 대기를 가지고 있음을 발견했습니다.하나의 큰 파일을 읽는 Java 다중 스레드

모든 스레드가 공유하는 바이트 배열에 파일을로드하는 것을 고려했습니다. 각 스레드는 ByteArrayInputStream을 만들지 만 1GB 바이트 배열을 할당하면 제대로 작동하지 않습니다.

또한 하나의 FileChannel과 각 스레드가 Channels.newInputStream()을 사용하여 InputStream을 작성하는 것으로 간주했지만 입력 스트림의 상태를 유지하는 것은 FileChannel 인 것으로 보입니다.

+1

각 스레드가 파일의 전체 내용을 필요로합니까? 또는 각각은 필요한 관련 데이터를 찾을 수 있습니까? –

+0

각 스레드는 전체 파일을 읽어야합니다. – bob

+0

시스템에는 8GB의 메모리가 있으며 1GB 어레이를 할당해도 괜찮습니다. 그러나 JVM은 이것을 좋아하지 않는다. 100 % cpu를 사용하여 어레이를 오랫동안 할당하려고한다. – bob

답변

10

IO 충돌을 피하려면 이 있습니다. 메모리에 파일을로드해야합니다. 운영 체제는 버퍼링을 일부 수행하지만, 충분하지 않다는 것을 알게되면 직접 처리해야합니다.

정말로 32 개의 스레드가 필요합니까? 아마 당신은 거의 코어를 가지고 있지 않으므로 쓰레드 수를 줄이면 컨텍스트 스위칭 등을 줄일 수 있습니다.

스레드가 모두 파일을 처음부터 끝까지 처리합니까? 그렇다면 효과적으로 파일을 청크로 분할 할 수 있습니까? 처음 10MB의 데이터를 메모리로 읽어 들이고 모든 스레드가 처리하도록 한 다음 다음 10MB 등으로 이동하십시오.

그래도 작동하지 않는다면, 얼마나 많은 메모리를 파일 크기? 많은 양의 메모리가 있지만 하나의 거대한 배열을 할당하고 싶지 않다면 전체 파일을 메모리로 읽을 수 있지만 더 작은 바이트 배열로 나누어 읽을 수 있습니다. 그런 다음 모든 바이트 배열에 걸친 입력 스트림을 작성해야하지만 그렇게 할 수 있어야합니다.

+0

@jon, Java 구조체를 디스크의 파일에 맵핑하는 것이 nio 툴을 사용하여 자바 구조체를 작성하고 JVM/OS가 실제 읽기 정보를 처리하는 방법을 알아내는 것이 필요합니다. ? –

+1

@Thorbjorn : Java는 메모리 매핑 된 파일을 지원합니다.하지만 OS보다 파일을 어떻게 사용할지에 대한 정보가 더 많으면 더 잘 수행 할 수 있습니다. –

1

몇 가지 아이디어 :

  1. 이되는 FileChannel에 대한 뷰 역할을하는 사용자 지정의 InputStream 구현을 작성합니다. FileChannel의 어떤 상태에도 의존하지 않도록 작성하십시오. (즉, 각 인스턴스는 자신의 위치를 ​​추적해야하며 기본 FileChannel에 대한 읽기는 절대 읽기를 사용해야합니다.) 적어도 Channels.newInputStream()에서 발생했던 문제를 해결할 수 있지만 IO 충돌 문제는 해결되지 않을 수 있습니다 .

  2. MappedByteBuffer에 대한보기 역할을하는 사용자 지정 InputStream 구현을 작성합니다. 메모리 매핑은 실제로 모든 것을 메모리에 실제로 읽는 것만 큼 나쁘지는 않지만, 여전히 1GB의 가상 주소 공간을 차지합니다.

  3. # 1과 동일하지만 일종의 공유 캐싱 계층이 있습니다. 나는 1이 충분히 효율적이지 않고 2가 실현 가능하지 않으면 이것을 시도하지 않을 것이다. 실제로, OS는 # 1에서 이미 캐싱을하고있을 것이므로 여기서는 OS 파일 시스템 캐싱보다 더 똑똑해 지려고 노력하고 있습니다.

5

읽기 전용 모드에서 파일을 여러 번 열 수 있습니다. 원하는 방식으로 파일에 액세스 할 수 있습니다. OS에 캐싱 만 남겨주세요. 속도가 너무 느린 경우 모든 스레드가 동일한 캐시에 액세스 할 수있는 일종의 청크 기반 캐싱을 고려할 수 있습니다.

0

매우 큰 파일입니다. 파일을 더 작은 파일 세트로 전달할 수 있습니까? 이 파일을 전달하는 것만으로도 회사 네트워크에서도 큰 성과를 거둘 수 있습니다.

때로는 프로그램보다 프로세스를 변경하는 것이 더 쉽습니다.

파일을 여러 청크로 분할하여 별도로 처리하는 것이 더 나을 수도 있습니다.

관련 문제