Wednesday, April 08, 2009

Some facts about the JVM used by Google's App engine

As you probably have noticed Google has released Java support for it's App Engine!

I wrote a small servlet to find out more about which Java they are running:

java.specification.version: 1.6
java.vendor: Sun Microsystems Inc.
line.separator:

java.class.version: 50.0
java.util.logging.config.file: WEB-INF/logging.properties
java.specification.name: Java Platform API Specification
java.vendor.url: http://java.sun.com/
java.vm.version: 1.6.0_13
os.name: Linux
java.version: 1.6.0_13
java.vm.specification.version: 1.0
user.dir: /base/data/home/apps/wanlatency/1.332645732335305520
java.specification.vendor: Sun Microsystems Inc.
java.vm.specification.name: Java Virtual Machine Specification
java.vm.vendor: Sun Microsystems Inc.
file.separator: /
path.separator: :
java.vm.specification.vendor: Sun Microsystems Inc.
java.vm.name: Java HotSpot(TM) Client VM
file.encoding: ANSI_X3.4-1968
Total Memory 104857600
Free Memory 6293011

Note that the Free Memory does not change if you allocate 10Mbyte (nor the Total memory). It might therefore by faked.
Allocating 1Gbyte results in a very simplistic error.

They use jetty!


java.lang.OutOfMemoryError: Java heap space at org.kohlerm.wanTestGoogleServlet.doGet(wanTestGoogleServlet.java:24) at javax.servlet.http.HttpServlet.service(HttpServlet.java:689) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093) at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360) at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712) at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:237) at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139) at org.mortbay.jetty.Server.handle(Server.java:313) at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506) at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:830) at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:63) at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381) at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:125) at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235) at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4547) at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4545) at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24) at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359) at com.google.net.rpc.impl.Server$2.run(Server.java:792) at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56) at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:489) at com.google.net.rpc.impl.Server.startRpc(Server.java:748) at com.google.net.rpc.impl.Server.processRequest(Server.java:340)



Because my "hobby" is memory usage analysis, I ran another test on the appengine and it seems you can allocate about 110Mbyte.
Allocation seems to be very slow. I first tried to allocate a byte array in 1Mbyte steps, but until it reached 100 Mbyte it would need 30 seconds "CPU time".
Maybe they persist larger blocks to disk???


14 comments:

Prashant Deva said...

Interesting that they use the 'client' vm and not the 'server' vm.

chris☆lewis said...

Interesting. I got into the Java beta and grabbed the local SDK. I haven't played with it yet, but one of the first things I did was glance at the server they chose: Geronimo. I've not used Geronimo, but a quick google says that Jetty is the container used in Geronimo. Thanks for the sharing the info!

Unknown said...

Hi Chris,
Geronimo, that's interesting. It would make sense that they would also use Geronimo on the server then, also we cannot be sure. Hmm maybe I should try to use JPA ...

gorlok said...

Nice and interesting.

Unknown said...

Client makes sense in this instance as startup time is more important than long term optimisation.

Marcus Breese said...

Just because they use Jetty doesn't mean that Geronimo is being used. Jetty is a very common Java web server that is known for being small and fast. It's also designed to be embedded in a variety of environments. So, I'd suspect that Jetty is being used standalone.

knowtheory said...

Are you getting this info dump from the dev env? or did you pull this info from an app running on the cloud?

Unknown said...

The stack trace above is from a servlet running on the cloud.
It's running at http://wanlatency.appspot.com/wantestgoogle

Prashant Deva said...

@Brett I dont see how startup time is so important. server side applications usually run for a long time once they are started, hence there is a server vm. since google app engine is all server side stuff it seems they would be better served with the server vm.

_lowell said...

@Markus

thanks for the info; btw you have a js somewhere blocking the Page Back while using Safari 4 in Mac OS 10 - i'm able to exit the page fine in Firefox 3.

Thilo said...

Interesting data points. Maybe you can periodically run the same test again, to see if they seem to gradually enhance the service (as Google usually does).

I am running a similiar experiment to try to figure out when JVM and threads are spawned. Please have a look: http://digg.com/d1oSB1

Thilo said...

@Prashant
Startup time could be important because Google wants to be able to fire up more servers and shut down unused ones as demand fluctuates.

Anonymous said...
This comment has been removed by a blog administrator.
Unknown said...

I am very frankly to say that each & every info is sharing by you for all types’ topics and solutions. This is the best information to jave programmers. You are really great going.

Mobile App Development Services