2009-07-14 2 views
18

나는 C 응용 프로그램과 통신해야하는 Java 응용 프로그램을 만들고 있습니다. C 응용 프로그램은 공유 메모리와 mmap을 사용하여 통신하며 동일한 메모리에 액세스 할 수 있도록 Java 응용 프로그램이 필요합니다.mmap과 마찬가지로 Java에서 메모리에 액세스하는 가장 좋은 방법은 무엇입니까?

첫 번째 시도는 공유 메모리에서 데이터를 검색하기 위해 JNI 호출을 사용했지만 각 JNI 호출의 오버 헤드로 인해 성능이 저하되었으므로 Java에서 해당 메모리에 액세스하고 데이터 검색을 수행하는 방법을 원합니다. 자바 측. (나는 새로운되는 FileChannel을 만들기

  • 에 연결하는 데 필요한 공유 메모리 위치의 위치를 ​​얻을 수

    1. 하나를 사용 JNI 호출 :

      내가 가진 생각은 내가 다음을 수행해야 할 것이다)되는 FileChannel는 MappedByteBuffer 사용하여지도를()

    만들

  • 사용이이 작업을 수행하는 가장 좋은 방법이 있나요? 또한 올바른 메모리 위치를 가리 키도록 실제로 FileChannel을 만드는 방법을 잘 모르겠습니다.

  • +0

    imho 할 수는 없지만 수정하는 것을 좋아합니다. – dfa

    답변

    11

    ByteBuffer.allocateDirect으로 조사하십시오. 분명히 이러한 버퍼는 JNI 레이어를 통해 메모리에 직접 액세스 할 수있는 원시 코드로 전달 될 수 있습니다.

    힌트는 this page (아래 인용)을 참조하십시오.

    이제 JNI 코드는 ByteBuffer로 만든 버퍼 내부의 네이티브 메모리 공간 주소를 알아낼 수있을뿐만 아니라,Java 측에서 allocateDirect()를 호출하지만 자체 메모리 (예 : malloc())를 할당 한 다음 JVM으로 다시 호출하여 새 ByteBuffer 객체에서 해당 메모리 공간을 래핑 할 수 있습니다. JNI 메소드는 NewDirectByteBuffer()).

    +1

    이것은 자바에서 얻을 수있는만큼 금속에 가깝습니다. 불행히도 ByteBuffer는 여전히 VM 경계를 넘어 정보를 가져와야합니다. JDK가 Deflator를 구현하는 방법을 살펴 보는 것이 도움이 될 수 있습니다. - http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/Deflater.html –

    +2

    ByteBuffers 그들은 환상적으로 일했습니다. JNI 코드에서 ByteBuffer를 작성한 다음 Java 코드로 리턴하여 Java 코드로 직접 액세스 할 수있었습니다. 결국 Java 응용 프로그램은 메모리를 읽고이를 쓸 수 있습니다. 쓰기는 동일한 메모리를 사용하는 C/C++ 응용 프로그램에서 즉시 볼 수 있습니다. – Brian

    -2

    C로 파일에 데이터를 저장 한 다음 Java에서 파일에 액세스 할 수 있다면 가장 좋을 것입니다. AFAIK 당신은 자바를 사용하고자하는 방식으로 메모리를 가리킬 수 없습니다.

    +0

    이것은 잘못되었습니다. 다이렉트 바이트 버퍼는 원하는 기능을 제공합니다. –

    0

    C 및 Java 응용 프로그램을 모두 소유하고 있다면 콘솔 스트림을 통해 통신 할 수 있습니다. 이진 데이터는 추악하지만 가능합니다. 더 많은 메시지 전달 스타일을 위해 공유 메모리를 교환 할 것입니다. TCP/IP 소켓 쌍.

    Btw, 어떤 데이터가 전달되고 얼마나 큽니까?

    +0

    크기가 정확히 맞지 않습니다. Gb에 대략 800Mb 일 수 있었다. 불행히도, 나는 C 애플리케이션을 수정하는 사치가 없다. – Brian

    +0

    원본 C 응용 프로그램을 래핑하는 새 C 응용 프로그램을 만듭니다. 일단 그렇게하면 kd304의 솔루션이나 AlbertoPL의 솔루션이 가능해야합니다. – NamshubWriter

    +0

    앱간에 전체 데이터를 이동해야합니까? – akarnokd

    1

    난 작은 C 모듈을 작성합니다 다른 응용 프로그램이 해당 메모리를 참조 할 수 있도록 공유 메모리와 사용 된 소켓을 mmaps (예를 들어, 자바 응용 프로그램)

    0

    당신이 몇 가지 기본 방법과 자바 클래스를 쓸 수 없습니다, 쓰기 C에서 네이티브 메소드 구현은 mmap을 사용하여 원하는 것을 수행한다. 그런 다음이를 기본 라이브러리로 컴파일하고 LD_LIBRARY_PATH를 사용하여 런타임에 추가하십시오. 이것은 JNI 오버 헤드없이 Java에서 네이티브 C 호출을 할 수있게합니다 (필자는 생각합니다). 여기

    일부 자습서 : link

    예를 들어, 당신이 쓰는 것 자바 클래스와 같은 :

    JMMap.h 
    
    JNIEXPORT void JNICALL Java_JMMap_write(JNIEnv *, jobject); 
    
    : 그런 식으로 뭔가를 생산하기 위해 클래스 파일에 대해 javah의 실행

    JMMap.java 
    
    public class JMMap { 
        public native void write(...) 
    } 
    

    .c 파일에서이를 구현하십시오. 라이브러리로 컴파일하십시오. 그것을 LD 경로에 추가 한 다음 Java 함수를 호출하십시오.

    관련 문제