I have been suffering from memory leaks for a long time about my web project. and I couldnot figure out what's wrong with it.
When the project starts, it only need 600m memory, and then it grows gradually. After 3 days, the memory cost will be around 4g and then it will freeze soon, which means it wont accept any request anymore.
I printed the jmap info just before it froze several days before.
num #instances #bytes class name
----------------------------------------------
1: 14496 2845179264 [Ljava.lang.Object;
2: 285578 48162912 [B
3: 8754 40270440 [I
4: 1029353 32939296 java.util.HashMap$Entry
5: 686482 27459280 org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext
6: 1704148 27266368 java.lang.Object
7: 170290 20434800 org.jboss.netty.channel.socket.nio.NioAcceptedSocketChannel
8: 170401 19084912 java.net.SocksSocketImpl
9: 170306 19074272 sun.nio.ch.SocketChannelImpl
10: 681195 16348680 java.net.InetSocketAddress
11: 170290 14985520 org.jboss.netty.handler.codec.http.HttpRequestDecoder
12: 160676 14204712 [C
13: 183171 11868480 [Ljava.util.HashMap$Entry;
14: 340694 10902208 java.net.Inet4Address
15: 340578 10898496 org.jboss.netty.util.internal.ConcurrentHashMap$HashEntry
16: 74687 10846416 <constMethodKlass>
17: 74687 8972232 <methodKlass>
18: 171989 8255472 java.util.HashMap
19: 511038 8176608 java.util.concurrent.atomic.AtomicInteger
20: 170306 8174688 sun.nio.ch.SocketAdaptor
21: 170291 8173968 org.jboss.netty.channel.AbstractChannel$ChannelCloseFuture
22: 170290 8173920 org.jboss.netty.channel.socket.nio.DefaultNioSocketChannelConfig
23: 6637 7213720 <constantPoolKlass>
24: 215371 6891872 java.lang.String
25: 170810 6832400 java.lang.ref.Finalizer
26: 170289 6811560 sun.nio.ch.SelectionKeyImpl
27: 107356 6780112 <symbolKlass>
28: 6637 6192456 <instanceKlassKlass>
29: 347511 5560176 java.lang.Integer
30: 170307 5449824 [Ljava.nio.channels.SelectionKey;
31: 170291 5449312 org.jboss.netty.channel.DefaultChannelPipeline
32: 169465 5422880 org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor
33: 170482 4091568 java.util.concurrent.ConcurrentLinkedQueue$Node
34: 170420 4090080 java.io.FileDescriptor
35: 170300 4087200 java.util.concurrent.ConcurrentLinkedQueue
36: 170290 4086960 org.jboss.netty.channel.socket.nio.AbstractNioChannel$WriteRequestQueue
37: 170290 4086960 org.jboss.netty.util.internal.ThreadLocalBoolean
38: 170290 4086960 org.jboss.netty.handler.codec.replay.ReplayingDecoderBuffer
39: 5787 4024984 <constantPoolCacheKlass>
40: 89657 3586280 java.util.LinkedHashMap$Entry
41: 106274 3400768 play.core.server.netty.PlayDefaultUpstreamHandler
...
Today, i use MAT to analyze dump info in eclipse, the leak suspect is:
51,084 instances of"org.jboss.netty.channel.socket.nio.NioAcceptedSocketChannel", loaded by"sun.misc.Launcher$AppClassLoader @ 0x715c0a240" occupy 756,863,880 (89.90%) bytes.
Biggest instances:
- org.jboss.netty.channel.socket.nio.NioAcceptedSocketChannel @ 0x73941d418 - 16,785,968 (1.99%) bytes.
- org.jboss.netty.channel.socket.nio.NioAcceptedSocketChannel @ 0x73d3e1270 - 16,785,928 (1.99%) bytes.
- org.jboss.netty.channel.socket.nio.NioAcceptedSocketChannel @ 0x71b69cb78 - 16,785,496 (1.99%) bytes.
- org.jboss.netty.channel.socket.nio.NioAcceptedSocketChannel @ 0x726f98950 - 16,785,464 (1.99%) bytes.
Keywords
sun.misc.Launcher$AppClassLoader @ 0x715c0a240
org.jboss.netty.channel.socket.nio.NioAcceptedSocketChannel
The project is quite simple, it is used to accept the photos sent from client and then upload them to amazons3, or push apns msg to client.
Application.java:
@BodyParser.Of(value = BodyParser.Raw.class, maxLength = ImgHandler.MAX_PIC_LENGTH)
public static Result upload_pic(final String key) {
final Request req = Application.request();
return async(
future(new Callable<String>() {
public String call() {
return ImgHandler.upload_pic(req, key);
}
}).map(new F.Function<String,Result>() {
public Result apply(String i) {
return ok(i);
}
})
);
}
I found the similar problem here:
http://web.archiveorange.com/archive/v/ZVMdI4hq8Mz7GLAFDnbSHis problem was that TimerTask can not be gc. I also have a TimerTask in my code, but I cannot find the bug...
public static class MyActor extends UntypedActor{
static ActorRef instance = Akka.system().actorOf(new Props(MyActor.class));
public static void init(){
try
{
// Send a TICK message every minute
Akka.system().scheduler().schedule(
Duration.Zero(),
Duration.create(1, TimeUnit.MINUTES),
instance, "TICK",
Akka.system().dispatcher()
);
}catch(Exception ex)
{
System.out.println("timer error:" + ex.toString());
}
System.out.println("schedule started");
}
public void onReceive(Object message) {
if("TICK".equals(message))
doSth();
}
}
I init the timer when the server start.(MyActor.init()).