2009-11-06 2 views
3

iSeries 상자 (JDK 1.5)에서 실행중인 일부 Java NIO 코드에 문제점이 있습니다. 기본적으로 코드는 파일을 다른 작은 파일로 청크 부분으로 분할합니다. 동일한 코드가 다른 AS/400 시스템에서도 문제없이 작동합니다. 여기iSeries의 NIO 파일 채널 전송 문제

//copy original data file content to temp file 
long startPos = dataFile.length() - remaining; 
long transferSize = maxSizeBytes - size; 
size += inChannel.transferTo(startPos, transferSize, outChannel); //exception here 
remaining -= size; 

스택 추적 것 : 여기에 코드입니다

Caused by: java.io.IOException: Operation not supported. Map failed 
at java.lang.Throwable.<init>(Throwable.java:196) 
at java.lang.Exception.<init>(Exception.java:41) 
at java.io.IOException.<init>(IOException.java:40) 
at sun.nio.ch.FileChannelImpl.map0(Native Method) 
at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:742) 
at sun.nio.ch.FileChannelImpl.transferToTrustedChannel(FileChannelImpl.java:448) 
at sun.nio.ch.FileChannelImpl.transferTo(FileChannelImpl.java:521) 

... 나는 몇 가지 조사를하고 지금까지 원인 (상위 디렉토리의 파일 권한을했던

더 (11) , 메모리 부족, 공유 메모리 제어 QSHRMEMCTL 스위치 OFF, SAN 사용) 모두 실패한 것으로 판명되었습니다.

누구나이 특별한 문제에 경험이 있습니까?

감사합니다. Brad.

+0

dataFile.length()보다 당신이이 선 주위에 몇 가지 더 많은 코드를 표시 할 수 있습니다 통과 dataFile.length()

  • 보다 더? 나는이 모든 것에서 size 변수의 의미에 대해 불평한다. – rsp

  • +0

    특정 청크 또는 바이트 수에서 발생합니까? 아니면 시작시 실패합니까? 아니면 무작위로 발생합니까? – cafebabe

    +0

    iSeries와 IBM JVM (32 비트 또는 64 비트). 내가 아는 한, 32 비트 VM에는 3GB 힙 한계가 있으며 NIO는 훨씬 제한되어 있습니다. – cafebabe

    답변

    0

    this thread (NIO 소스를 기준으로 인수를 지원함)에 따르면 가능한 원인은 메모리 부족 조건입니다.

    +0

    그래, 그걸 보았습니다. 그 소스가 Sun JDK 구현이므로 반드시 같지는 않다고 가정하고 있습니까? 그렇다고 가정하면 작은 파일 (커플 K)에 대해 실행되는 테스트 클래스를 사용하여 동일한 오류를 발생시킬 수 있었지만 여전히 실패했습니다. 또 다른 요인으로, 2gig 힙 크기와 376 바이트의 데이터 파일로 인해 초기 오류가 발생했습니다! 아직도 가능하지만 가능성은 희박합니다. 어쩌면 나는 ~ Xmx 실험을 시도해야한다. – Brad

    +0

    메모리 부족 상태는 Java 힙이 아닌 OS 부분에있을 가능성이 큽니다 (mmap을 수행하려고 시도하고 있으므로). –

    1

    파일 핸들 제한에 도달하면 JVM에서 발생하는 명백한 예외가 발생할 수 있다는 사실을 기억해야합니다.

    사용할 수있는 파일 핸들이 충분한 지 확인하십시오. ulimit은 처분 할 수있는 수를 알려줍니다. (물론, 데몬 인 경우 JVM이 실행중인 사용자에 대해이 번호를 알고 싶을 것입니다.)이 문제는 시스템/사용자마다 다를 수 있습니다.이 문제는 다른 곳에서 실행되는 사실에 대한 사용자의 설명에 다소 부합합니다 잘 됐네.

    +0

    안녕하세요, Stu, 재미있는 점, 이것을 확인하겠습니다. – Brad

    +0

    Stu - 대상 사용자 계정에서이 값을 확인한 경우 반환 값은 "무제한"입니다. – Brad

    +0

    그게 아니야! 파머. –

    0

    OK, 또 다른 기회 : 더 많은 코드를 게시 할 수 있습니까? 모든 생존자 및 제어 루프의 초기화와 같습니다. 다른 곳에서 일하는 것을 말하고 있지만 몇 가지 사항에 대해 궁금해하고 그렇게 무시했습니다.

    1: long startPos = dataFile.length() - remaining; 
    2: long transferSize = maxSizeBytes - size; 
    3: size += inChannel.transferTo(startPos, transferSize, outChannel); //exception here 
    4: remaining -= size; 
    
    1. remaining는 루프의 dataFile.length() 외부로 초기화되어 있습니까? 그렇지 않다면 항상 시작부터 날려 버릴 것입니다.
    2. size의 이름은 아마도 bytesTransfered 일 수 있습니다. 나는 약간 혼란스러워졌다.
    3. remainingsize 변수가 모두 필요하지 않습니다. 하나, 다른 하나는
    4. maxSizeBytes이 값 <으로 초기화된다 충분해야 =
    5. dataFile.length() 당신은 startPos, transferSizedataFile.length()를 로그인 할 수 있습니까? 어쩌면 당신이 통과 실수
      1. 있는지 궁금 해요 transferSize 큰이 startPos
    +0

    스투, 다시 보아 주셔서 고맙습니다. 첫 번째 대답에서 언급 한 전송 크기의 코드를 약간 수정했지만 도움이되지 않았습니다. 우리는이 문제가있는 시스템에서 선택할 수있는 NIO가 아닌 코드 경로를 추가하여이 문제를 해결했습니다. 도와 주셔서 감사 드리며 관심을 가져 주셔서 감사합니다. – Brad