ByteBuffer, FloatBuffer, IntBuffer등의 자바에서 제공하는 버퍼 클래스가 있다 (모두 Buffer로부터 상속되었다)
이 클래스들은 BLOB의 역활을 한다
내부에 오프셋이 있어서 파일처럼 읽고 쓸 수 있다.
getInt() 등의 메소드로 읽으면 오프셋이 이동해서 두번째 호출하는 getInt() 는
파일에서 fread를 하는것처럼 다음 값을 가져다준다.
OpenGL의 버텍스버퍼 생성 코드를 보다보면
mFloatVertexBuffer = ByteBuffer.allocateDirect(FLOAT_SIZE * size * 3)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
식으로 궂이 ByteBuffer를 생성한후 이를 asFloatBuffer() 등으로 변경하여 FloatBuffer를 사용하는데
여기엔 이유가 있다!
ByteBuffer만이 allocateDirect() 메소드를 가지고 있기 때문이다.
allocateDirect() 로 할당된 메모리는 Java의 GC Heap 에서 벗어난 곳에 할당될 수 있으며
JVM은 direct메모리 read/write시 최대한 native에 가까운 속도로 입출력을 하도록 노력을 하게 된다
하지만 그만큼 alloc/dealloc시 일반적인 자바 메모리 alloc/dealloc 보다 더 많은 비용이 들기 때문에
프로그램 실행후 오랜 시간동안 유지되는 메모리에만 사용해야지,
lifetime이 짧은 곳에다 쓰면 성능에 문제가 발생하게 된다
추가 – 찾아봤는데 직접 delete하는 함수는 없다.. 역시 자바라 dealloc은 GC에서만 하는 것 같다 -_-
delete하듯 포인터(?)를 null으로만 설정해 두자.
여기까지 알아보니 ByteBuffer라는걸 제공하는 이유가
성능이 중요한 곳에서 메모리를 JAVA GC가 관리하게 하지 않고
직접 이런식으로 메모리 할당을 하기 위해서라고 자동으로 깨닫게 됐고
JAVA에서 커스텀 메모리 관리자를 만들때에 필수적으로 써야하는 것이라는걸 직감했따
그리고 allocateDirect()호출 후 order() 메소드를 호출해서 nativeOrder() 라는것으로 세팅을 해주고 있는데
Little Endian/Big Endian 중 현재 하드웨어에서 사용되는 native order를 가져와서 해당 order로
Buffer를 다루도록 설정해서 버퍼를 빨리 다룰수 있게 하고 있는 것이다
원글 : http://cretom.egloos.com/m/2823473
참고
http://download.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html
http://download.oracle.com/javase/1.4.2/docs/api/java/nio/ByteOrder.html#nativeOrder()

13 Replies to “ByteBuffer, FloatBuffer, IntBuffer”