1

I am using Play 2.4 with dependency injection and injected route generator. But on first request, it is taking 1200 ms and after that, it takes 20 ms for the requests to same route. After i debug it more, i found that on first request, it was loading about 1000 classes using java.lang.classLoader.loadClass(String) method.

[Loaded org.jboss.netty.handler.codec.frame.FrameDecoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.replay.ReplayingDecoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpMessageDecoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpRequestDecoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.replay.ReplayError from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.frame.TooLongFrameException from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpChunk from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpChunkTrailer from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpMessageDecoder$State from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpMessage from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.replay.ReplayingDecoderBuffer from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.replay.UnreplayableOperationException from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.oneone.OneToOneEncoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpMessageEncoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.handler.codec.http.HttpResponseEncoder from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.util.CharsetUtil from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.util.CharsetUtil$1 from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.util.CharsetUtil$2 from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]
[Loaded org.jboss.netty.buffer.ChannelBuffers from file:/Users/tushar7795/Reach/reach-api/reach-api-1.0.0/lib/io.netty.netty-3.10.5.Final.jar]

These are some of the classes which are being loaded on first request. How can i load these classes on application start up?

erhun
  • 3,549
  • 2
  • 35
  • 44
  • I think this layz loading of classes is normal behaviour of the JVM. Why would you want to change it? – Kris Jun 23 '16 at 13:59
  • This may come from Guice also. You could try to add a hook at startup to make a request on the server itself to force it to load the classes – vdebergue Jun 23 '16 at 14:08
  • @Kris because of this, after server restart, whoever makes first request need to wait too much. Apart from that, it was also spoiling average response time statistics in newrelic. – Tushar Santoki Jun 23 '16 at 17:25
  • How are you running your application? – marcospereira Jun 24 '16 at 01:43
  • @marcospereira in production mode (using sbt dist) – Tushar Santoki Jun 24 '16 at 05:24
  • Maybe you could just fake a request right after startup of your app. This would force the loading of your classes. Or you could give this `Class.forName(String className)` a try that they are talking about in http://stackoverflow.com/questions/25178154/how-to-preload-classes-in-java. But I've never used it myself. – Kris Jun 24 '16 at 15:52
  • Another possibility could be to use the server JVM (http://stackoverflow.com/questions/5272674/what-is-jvm-server-parameter). You can use `-J-server` parameter (https://www.playframework.com/documentation/2.2.x/ProductionConfiguration#Specifying-additional-JVM-arguments). I hope this helps. – Kris Jun 24 '16 at 18:43
  • @Kris that also didn't help and loading classes manually is not a smart way. – Tushar Santoki Jun 25 '16 at 18:28

1 Answers1

0

If you don't want that your initial requests to app takes more time because of JVM's lazy loading behaviour, One solution is to create external script which will warmup your application and don't return 200 on health-check until warmup is finished. One another way is to create akka actor which will warmup your app. You can initialize this actor using fire-forget method(tell) after app start-up and same as above, fail health-check until warmup is finished so that ELB don't start redirecting requests to this instance.