Last active
December 23, 2015 02:29
-
-
Save codingtony/6566869 to your computer and use it in GitHub Desktop.
Trying to output 1GB of zero bytes in chunks. Seems to have a memory leak....
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Start with : | |
mvn compile exec:exec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>netty-bug</groupId> | |
<artifactId>netty-bug</artifactId> | |
<version>0.0.1-SNAPSHOT</version> | |
<build> | |
<sourceDirectory>./</sourceDirectory> | |
<plugins> | |
<plugin> | |
<artifactId>maven-compiler-plugin</artifactId> | |
<version>2.3.2</version> | |
<configuration> | |
<source>1.7</source> | |
<target>1.7</target> | |
</configuration> | |
</plugin> | |
<plugin> | |
<groupId>org.codehaus.mojo</groupId> | |
<artifactId>exec-maven-plugin</artifactId> | |
<version>1.2.1</version> | |
<configuration> | |
<executable>java</executable> | |
<arguments> | |
<argument>-cp</argument> | |
<classpath/> | |
<argument>TestOutOfMemory</argument> | |
</arguments> | |
</configuration> | |
</plugin> | |
</plugins> | |
</build> | |
<dependencies> | |
<dependency> | |
<groupId>io.netty</groupId> | |
<artifactId>netty-codec-http</artifactId> | |
<!-- | |
<version>4.0.8.Final</version> | |
--> | |
<version>4.0.10.Final-SNAPSHOT</version> | |
</dependency> | |
</dependencies> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; | |
import static io.netty.handler.codec.http.HttpResponseStatus.OK; | |
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; | |
import io.netty.bootstrap.ServerBootstrap; | |
import io.netty.channel.ChannelFuture; | |
import io.netty.channel.ChannelFutureListener; | |
import io.netty.channel.ChannelHandlerContext; | |
import io.netty.channel.ChannelInitializer; | |
import io.netty.channel.ChannelPipeline; | |
import io.netty.channel.EventLoopGroup; | |
import io.netty.channel.SimpleChannelInboundHandler; | |
import io.netty.channel.nio.NioEventLoopGroup; | |
import io.netty.channel.socket.SocketChannel; | |
import io.netty.channel.socket.nio.NioServerSocketChannel; | |
import io.netty.handler.codec.http.DefaultHttpResponse; | |
import io.netty.handler.codec.http.FullHttpMessage; | |
import io.netty.handler.codec.http.HttpHeaders; | |
import io.netty.handler.codec.http.HttpObjectAggregator; | |
import io.netty.handler.codec.http.HttpRequestDecoder; | |
import io.netty.handler.codec.http.HttpResponseEncoder; | |
import io.netty.handler.codec.http.LastHttpContent; | |
import io.netty.handler.stream.ChunkedStream; | |
import io.netty.handler.stream.ChunkedWriteHandler; | |
import java.io.BufferedInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.lang.management.ManagementFactory; | |
import java.net.InetSocketAddress; | |
import java.net.SocketAddress; | |
import java.util.Date; | |
import java.util.concurrent.Executors; | |
import java.util.concurrent.TimeUnit; | |
public class TestOutOfMemory { | |
final static int GIGABYTE = (4 * 1024 * 1024); // multiply 256B = 1GB | |
/** | |
* @param args | |
*/ | |
public static void main(String[] args) throws Exception { | |
boolean printHeap = false; | |
if (printHeap) { | |
Executors.newScheduledThreadPool(1).scheduleAtFixedRate( | |
new Runnable() { | |
@Override | |
public void run() { | |
String stamp = new Date().toString(); | |
System.out.printf("%s - Heap %s\n", stamp, | |
ManagementFactory.getMemoryMXBean() | |
.getHeapMemoryUsage()); | |
System.out.printf("%s - NonHeap %s\n", stamp, | |
ManagementFactory.getMemoryMXBean() | |
.getNonHeapMemoryUsage()); | |
} | |
}, 0, 3, TimeUnit.SECONDS); | |
} | |
EventLoopGroup bossGroup = new NioEventLoopGroup(); | |
EventLoopGroup workerGroup = new NioEventLoopGroup(); | |
try { | |
ServerBootstrap b = new ServerBootstrap(); | |
b.group(bossGroup, workerGroup); | |
b.channel(NioServerSocketChannel.class); | |
b.localAddress(new InetSocketAddress(8080)); | |
b.childHandler(new ChannelInitializer<SocketChannel>() { | |
@Override | |
protected void initChannel(SocketChannel ch) throws Exception { | |
createPipeline(ch); | |
} | |
}); | |
ChannelFuture f = b.bind().sync(); | |
f.channel().closeFuture().sync(); | |
} finally { | |
bossGroup.shutdownGracefully().sync(); | |
workerGroup.shutdownGracefully().sync(); | |
} | |
} | |
static public ChannelPipeline createPipeline(SocketChannel ch) { | |
ChannelPipeline pipeline = ch.pipeline(); | |
pipeline.addLast("decoder", new HttpRequestDecoder()); | |
pipeline.addLast("aggregator", new HttpObjectAggregator(65536)); | |
pipeline.addLast("encoder", new HttpResponseEncoder()); | |
pipeline.addLast("chunkedWriter", new ChunkedWriteHandler()); | |
pipeline.addLast(new SimpleChannelInboundHandler<FullHttpMessage>() { | |
@Override | |
public void channelWritabilityChanged(ChannelHandlerContext ctx) | |
throws Exception { | |
System.out.printf("Writability changed %s\n", ctx.channel() | |
.isWritable()); | |
for (StackTraceElement ste : Thread.currentThread() | |
.getStackTrace()) { | |
System.out.println(ste); | |
} | |
super.channelWritabilityChanged(ctx); | |
} | |
@Override | |
protected void channelRead0(ChannelHandlerContext ctx, | |
FullHttpMessage msg) throws Exception { | |
final SocketAddress remoteAddress = ctx.channel() | |
.remoteAddress(); | |
System.out.printf("New connection [%s] \n", remoteAddress); | |
DefaultHttpResponse response = new DefaultHttpResponse( | |
HTTP_1_1, OK); | |
HttpHeaders.setTransferEncodingChunked(response); | |
response.headers() | |
.set(CONTENT_TYPE, "application/octet-stream"); | |
ctx.write(response); | |
// This method is actually a lot faster, no memory leaks | |
// apparent. | |
InputStream is = new InputStream() { | |
int offset = -1; | |
byte[] buffer = null; | |
@Override | |
public int read() throws IOException { | |
if (offset == -1 | |
|| (buffer != null && offset == buffer.length)) { | |
fillBuffer(); | |
} | |
if (buffer == null || offset == -1) { | |
return -1; | |
} | |
while (offset < buffer.length) { | |
int b = buffer[offset]; | |
offset++; | |
return b; | |
} | |
return -1; | |
} | |
// this method simulates an application that would write to | |
// the buffer. | |
// ONE GB (max size for the test; | |
int sz = 1024 * 1024 * 1024; | |
private void fillBuffer() { | |
offset = 0; | |
if (sz <= 0) { // LIMIT TO ONE GB | |
buffer = null; | |
return; | |
} | |
buffer = new byte[1024]; | |
System.arraycopy(CONTENT_1KB_ZEROED, 0, buffer, 0, | |
CONTENT_1KB_ZEROED.length); | |
sz -= 1024; | |
} | |
}; | |
ctx.write(new ChunkedStream(new BufferedInputStream(is), 8192)); | |
try { | |
} finally { | |
ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT) | |
.addListener(new ChannelFutureListener() { | |
@Override | |
public void operationComplete( | |
ChannelFuture future) throws Exception { | |
System.out.printf( | |
"Closing connection [%s] \n", | |
remoteAddress); | |
} | |
}).addListener(ChannelFutureListener.CLOSE); | |
} | |
} | |
@Override | |
public void exceptionCaught(ChannelHandlerContext ctx, | |
Throwable cause) throws Exception { | |
System.out.println("Exception caught! " + cause); | |
for (StackTraceElement ste : cause.getStackTrace()) { | |
System.out.println(ste); | |
} | |
} | |
}); | |
return pipeline; | |
} | |
final static byte[] CONTENT_1KB_ZEROED = new byte[] { 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | |
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment