Java를 사용하여 매우 간단한 Thrift 서버를 구현했습니다.간단한 Java Thrift 서버가 메모리 부족 예외를 발생시킵니다.
이 서비스 SimpleServer.java
public class SimpleServer {
public static SimpleHandler handler;
public static SimpleService.Processor processor;
public static void main(String [] args) {
try {
handler = new SimpleHandler();
processor = new SimpleService.Processor(handler);
InetAddress listenAddress = InetAddress.getByName("localhost");
TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(
new InetSocketAddress(listenAddress, 9091));
TTransportFactory transportFactory = new TFramedTransport.Factory(
8 * 1024 * 1024);
THsHaServer.Args serverArgs = new THsHaServer.Args(serverTransport)
.processor(processor)
.transportFactory(transportFactory);
serverArgs.maxReadBufferBytes = (long) (256 * 1024 * 1024);
TServer server = new THsHaServer(serverArgs);
System.out.println("Starting server...");
server.serve();
} catch (Exception x) {
x.printStackTrace();
}
}
}
만, 바이너리 데이터를 받아 지정된 초 동안 휴면 데이터 길이를 반환하는 기능이있다. IDL 및 핸들러 구현에 대해서는 아래를 참조하십시오. 목적은 데이터베이스 배치 쓰기와 같은 큰 입력을 허용하는 느린 작업을 에뮬레이션하는 것입니다.
simple.thrift
public class SimpleHandler implements SimpleService.Iface{
@Override
public int hold(int seconds, ByteBuffer data) throws TException {
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return data.capacity();
}
}
namespace java generated
service SimpleService {
i32 hold(1:i32 seconds, 2:binary data);
}
SimpleHandler.java 그러면 I는 각각 1 초 대기 시간과 4메가바이트 이진 데이터 요청을 전송 1,000 동시 스레드를 시작하여이 서버를 테스트한다.
ByteBuffer buffer = ByteBuffer.allocate(4 * 1024 * 1024);
int result = client.hold(1, buffer);
초의 테스트 프로세스 수십를 실행 한 후, 서버는 내가 드리프트 소스 코드를 읽고, 가장 큰 메모리 소비가 읽기 버퍼의 할당 알고
java.lang.OutOfMemoryError: Java heap space
at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:57)
at java.nio.ByteBuffer.allocate(ByteBuffer.java:335)
at AbstractNonblockingServer$FrameBuffer.read(AbstractNonblockingServer.java:352)
at AbstractNonblockingServer$AbstractSelectThread.handleRead(AbstractNonblockingServer.java:184)
at TNonblockingServer$SelectAcceptThread.select(TNonblockingServer.java:182)
at TNonblockingServer$SelectAcceptThread.run(TNonblockingServer.java:133)
가 발생합니다. 메모리 부족을 방지하기 위해 serverArgs.maxReadBufferBytes
을 256MB로 설정했습니다. 하지만 여전히 Out of Memory 예외가 발생합니다. 나는 할당 된 읽기 버퍼가 정확하게 소스 코드를 읽고 일부 실행 정보를 인쇄함으로써 제한된다는 것을 확신합니다.
여전히 Out of Memory 예외가 발생하는 이유를 알 수 없습니다.
각 스레드가 4MB 인 1000 개의 스레드는 얼마입니까? ''Xms''와''Xmx''vm 매개 변수에 어떤 값을 사용합니까? – f1sh
hw에서 사용 가능한 메모리는 얼마입니까? – Erik
@ f1sh 각각 4MB입니다. 나는'Xms'와'Xmx'를 설정하지 않습니다. 기본 설정이어야합니다. 메모리 사용량을보기 위해'jvisualvm'을 사용합니다. 최대 힙 크기는 약 2G입니다. – gzc