October 5, 2009

News and restart of old News

Lets start with the new news.
I have created a self paced web training for JRockit Mission control.
You can find it - here

The training will have you using all the major parts of JRockit Mission Control, and is a good starting point in understanding what JRMC can do, and how it may help you and your team.
If you are at all curious about JRockit and JRockit Mission Control - give it a spin. If you have any questions or comments, please point them to the JRockit forums at http://forums.oracle.com/forums/forum.jspa?forumID=561 . In theory you could also leave comments here, at the blog, but that function is more or less DOS:ed by cheapmedz-ads, so I would strongly recommend the forums.

So, the restart of old news. Well, we have done monthly, public, webcasts for JRockit. We are now re-launcing that, but with a twist. Each month there will be a blog post on some JRockit related topic, and about one week after the post, there will be a webcast with the blog writer. The presentation will be mostly about the blog post, but there will also be an Q&A session towards the end where you will be able to ask any JRockit related question.

Some of the blog posts will discuss issues extremely low down in the JVM and be interesting but speak about things that the normal developer should not ever have to know. Other posts will have useful hints and tricks to get the most of your JVM. Our intention is to have presentations that we, ourselves, would find interesting. Some may even be useful.

The Schedule is (Topic names will be made more "selling" before presentation):
October 20th - Tomas Nilsson (Me) - General JRockit Presentation and introduction to the JRMC web training.
November - Stefan Särne - Using Verbose logs to manage reference objects.
December - Jossefin Dalstedt - Allocation paths, large objects and TLA.
January - Noora Peura - Name withheld since it hints to features not yet announced-
February - Henrik Edberg - Garbage Collection step-by-step
March - Anders Åstrand - Using opt_files in R27-x and R28-x

Dial in information for the October 20th weeks presentation is:
Meeting ID: 327979
Passcode 113113
From the AMER region dial: 1-888-967-2253 1-650-607-2253 From the APAC region dial: 1 800 222 712 (Australia toll-free) 800 9491 2777 61 2 8817 6100 From the EMEA region dial: 44 118 924 9000

Web invite for the EU/APAC 10:00 AM (CET) / 5:00 PM JST presentation here
Web invite for the US 7:00 PM (CET) / 10:00 am PDT/ 1:00 pm EDT presentation here

(The interested reader will note that the webex following this post is more than 1 week after the post. This is due to me beeing at Oracle Open World this year. This link has more information.)

September 11, 2009

For the love of the game

9 611 262
Now that is one big number...

Hey, I know a larger one you think, for example 9 615 973. But 9 611 262 is actually the highest one now, in the SPECjbb2005 high score list. For a long time I didn't think I was going to see the old world record broken, but here it is.

A couple of years ago, we worked with our friends at SGI and made a series of publications, the highest one of them was 5 180 451 SPECjbb2005 bops (80 945 SPECjbb2005 bops/JVM), which was the new world record. I was saying to myself, "Oh, well, this may actually kill the benchmark". To succeed on SPECjbb2005 you need good software and good hardware. In order to create a new world record in highest total score you need good and large hardware, The result from SGI was run on an Altix machine with 128 sockets, which I am fairly sure is a bit larger than the average closet server.

I was therefore quite happy too see the recent publication from 3Leaf. After too long time without a new world record, the stars were right for a new one. Of course I was happy to see that this world record also was based on JRockit. This also showed me that the "Highest total score" category of the benchmark wasn't dead yet, and the invigorated competition pleased me even more .

During a SPEC workshop we did a presentation about "our love of the game", me from Oracle (at that time BEA), Alan Adamson from IBM and Dave Dagastine from Sun. We all agreed on how much we enjoy the leapfrogging game that had been going on with the benchmark, driving the products forward at a very high rate, to the benefit of all our customers.

And the leapfrogging game continues, now with the most recent publication from SGI with 9 611 262 SPECjbb2005 bops (75 088 SPECjbb2005 bops/JVM). Will this monstrous high score finally kill the competition? Likely not. I know we at the JRockit team will keep improving our JVM, and I also know that the excellent techies at companies like SGI and 3Leaf will keep pushing the envelope. Until the next one.

With love for the game,
Stefan



SPEC Disclosure Statement
SPEC, SPECjbb reg tm of Standard Performance Evaluation Corporation.
Results as of 09/10/2009 on www.spec.org

Oct 26, 2007 - SGI - SPECjbb2005 bops = 5180451, SPECjbb2005 bops/JVM = 80945
BEA JRockit(R) 5.0 R27.4.0-90 (build R27.4.0-90-89592-1.5.0_12-20070928-1715-linux-ia64, compiled mode)
Altix 4700 (64 Blade/128P DC)
# of Chips 128, # of Cores 256
http://www.spec.org/jbb2005/results/res2007q4/jbb2005-20071030-00399.html

Jun 5, 2009 - 3Leaf Systems, Inc. - SPECjbb2005 bops = 5534233, SPECjbb2005 bops/JVM = 172945
Oracle JRockit(R) 6 P28.0.0 (build P28.0.0-29-114096-1.6.0_11-20090427-1758-linux-x86_64, compiled mode)
3Leaf Systems Voyager Platform, Quad-Core AMD Opteron(tm) Processor 8384
# of Chips 32, # of Cores 128
http://www.spec.org/jbb2005/results/res2009q3/jbb2005-20090609-00742.html

Jul 26, 2009 - SGI - SPECjbb2005 bops = 9611262, SPECjbb2005 bops/JVM = 75088
Oracle JRockit(R) (build R27.6.3-40_o-112056-1.5.0_17-20090318-2103-linux-ia64, compiled mode)
Altix 4700 (128 Blade/256 DC), Intel DC Itanium2 Processor 9040 1.6 Ghz
# of Chips 256, # of Cores 512
http://www.spec.org/jbb2005/results/res2009q3/jbb2005-20090727-00756.html

April 14, 2009

Webcast details added to previous posts

(No text, just added this to make sure a RSS update is triggered)

April 9, 2009

Monthly public JRockit webcasts. (Updated)

Starting with the release of JRockit Mission Control 3.1, we will have monthly webcasts for the JRockit products.

These webcasts will be open for anyone, no pre-enrolment required. We will have one time slot that should be suitable for Asia/Pacific and Europe, Midle East and Africa (APAC and EMEA in corp-speak), and another that should work better for the US.

Our intention with these web-casts is to spread the word about JRockit, but also to connect directly with our users. The presenter will have a prepared slide deck, about 1 hour worth of presentation, but will answer questions and adapt the presentation as much as possible to give you, the participant, the information that you are interested in. It is our hope that the presentations will evolve over time to reflect what you want to know, not what we believe you want.

Connection information will be added here as we get closer to the actual date.

JRockit monthly webcast EU/APAC (Public) 15-Apr-2009 10:00 AM (CET) / 5:00 PM JST

JRockit monthly webcast - US (Public) 15-Apr-2009 7:00 PM (CET) / 10:00 am PDT/ 1:00 pm EDT

Details - EU. Please note, conference software requires Internet Explorer

Copy and paste the following link into your browser:
https://conference.oracle.com/imtapp/app/cmn_jm_hub.uix?mID=141591600&loginRequired=y


Conference Details

Conference Title JRockit montly webex EU/APAC (Public)
Conference ID 141591600
Conference Key
Date and Time 15-Apr-2009 10:00 AM
Duration 1 Hour
Timezone (+01:00) Stockholm
Dial-In Number See below
Information Meeting ID: 327979
From the AMER region dial:
1-888-967-2253
1-650-607-2253
From the APAC region dial:
1 800 222 712 (Australia toll-free)
800 9491 2777
61 2 8817 6100
From the EMEA region dial:
44 118 924 9000
Passcode 113113

Invited Attendees Attendee list is not published.

Details - US
Copy and paste the following link into your browser:
https://conference.oracle.com/imtapp/app/cmn_jm_hub.uix?mID=141591748&loginRequired=y


Conference Details

Conference Title JRockit Public webast - US (Public)
Conference ID 141591748
Conference Key
Date and Time 10-Apr-2009 7:00 PM
Duration 1 Hour
Timezone (+01:00) Stockholm
Dial-In Number See below
Information Meeting ID: 327979
From the AMER region dial:
1-888-967-2253
1-650-607-2253
From the APAC region dial:
1 800 222 712 (Australia toll-free)
800 9491 2777
61 2 8817 6100
From the EMEA region dial:
44 118 924 9000
Passcode 113113

April 7, 2009

Oracle JRockit Mission Control 3.1 Available!

The new version of JRockit Mission Control is available! Yay! The 3.1 version features a much improved user interface, new extensibility features and an experimental update site with JRockit Mission Control add-ons.

See this blog entry for more information.

March 4, 2009

Oracle Technology Day (US)

Oracle Technology Day: Enterprise Application Foundation
Outperform your competitors while Lowering Operational Costs with WebLogic, Coherence, and Tuxedo

Enterprise Application Foundation Technology Day focused on WebLogic, Coherence, Tuxedo, and JRockit

1. Customers will join Oracle experts for an insightful keynote and technical sessions focusing on Oracle's WebLogic, Coherence, JRockit, and Tuxedo

2. Customers will learn from case studies, view product demonstrations, and get in-depth information on Oracle's fusion middleware foundation product strategy and roadmap.

3. Target audience -- IT managers, IT operations managers, architects, senior developers

Call to action:

1. To register for this event in Houston on March 24 click here.

2. To register for this event in Reston/VA on April 7click here

3. To register for all other cities click here

February 3, 2009

Why is my JVM process larger than max heap size?

(by Stefan Särne)

A perfectly valid question, and one that is hard to answer without knowing a bit about what goes on under the hood of your JVM (Java Virtual Machine).

This blog entry will give a short description of why this can be the case and also describe the diagnostic command in JRockit called print_memusage, which can be used to ask a running JRockit process how much memory it uses, and for what.

But why larger than -Xmx?
The command line argument -Xmx sets the maximum Java heap size (mx). All java objects are created on the Java heap, but the total memory consumption of the JVM process consist of more things than just the Java heap. A few examples:
- Generated (JIT:ed) code
- Loaded libraries (including jar and class files)
- Control structures for the java heap
- Thread Stacks
- User native memory (malloc:ed in JNI)

It is important to think of this when dimensioning how many processes that should run on a single server and what to set maximum heap size to. Usually the heap is by far the largest part of the process space, but the total size of the process will also depend on your application.

Reserved != Committed
It is easy to be alarmed by the number for reserved (or mapped) memory, but a process will not use any physical memory resources until it memory is committed. JRockit will for example reserve the heap up to maximum heap size, but not use it until needed. It will also, for example, reserve 1 GB for generated code on 64-bits X86 architectures, but only commit as is needed.

Understanding print_memusage

JRockit has a Diagnostics Command called print_memusage.

This little tool started with developers in the JRockit engineering team that wanted to understand in detail what the JVM used the memory for. After the development of the first version it became evident that the customers also wanted to know what the JVM uses the memory for, and what it actually means. This brief history is included so that you, as a user, will forgive us for not having a more user friendly tool. It will be improved in the next major release of JRockit (normal disclaimers on release predictions apply).

Memusage is a command that will ask the sub-systems in JRockit how much memory they are using, which in turn will walk through the memory it holds on to and report it. It will also ask the OS how much the process is indeed using and scan the virtual memory space for what type it is. This approach makes it possible to retrieve the information from any running JVM, without any cost until it is invoked. Due to technical limitations, the tool is “good” but not 100% exact.

In this example I use jrcmd to connect to JRockit in my local development environment.

print_memsuage_example.png

As you can see in this screen shot, the tool reports data hierarchically, starting with “Total mapped”, and then showing details broken down in smaller pieces.

Some things worth highlighting:
print_memsuage_example_total.png
The process has reserved/mapped about 1 GB of memory.
Out of that, about 708692 KB is in use, i.e. committed.
Both Total mapped and Total in-use are gathered from the OS.

print_memsuage_example_code_percentage.png
The process has 28544 KB as executable memory. This includes both native code, like the jvm library itself and code generated (jit:ed) by the jvm. In this example, 21.1% of the memory which is executable, is allocated by the compiler in the JVM, 5652 KB (or 94%) is currently in use. The fact that the total is higher than 100% is not as strange as it may seem.The JVM will pool the code memory and reuse it and only free it when a large enough amount is unused. There are several reason for code not being in use any more, for example if the method is optimized then the first version may no longer be needed, or if the class is unloaded. This is handled by the Code GC in JRockit.

print_memsuage_example_rw_memory.png
The largest chunk is usually the rw-memory, which includes the Java heap. The Stacks are the thread stacks, one for each thread. Under “classes” and under “malloced memory” is meta information about the java code, which is needed both for the JVM to keep track and for upholding the java model, like debug info when throwing exceptions. It also includes all static Strings, and all jar/zip handlers, which is live when reading from jar files.

If there is a number inside parenthesis, it indicates the number of items of the indicated type has been allocated. In the example above, the #97701 says that there are 97701 method structs.
print_memsuage_example_unaccounted_for.png

In unaccounted for is "the rest", in other words the difference between the total in use and what the subsystems are responsible for. It includes some fragmentation in the memory malloced by the JVM, but also memory allocated from JNI code.

Summary
So this is a neat little tool to get insight into the process memory. Whoever said that memory is cheap these days? I hope this will serve as a good starting point to understand where all the memory goes.

JRockit blog launch message.

Welcome to the first in a new series of JRockit blog posts. This blog used to belong to Henrik Ståhl, but since he claimed the best url, we have hijacked it and will be making posts here from the entire JRockit team.

First out in our line-up of posters is Stefan Särne. Stefan has been working in the JRockit Engineering Team for the past six years, and has experienced the transition from Appeal Virtual Machines to BEA Systems Inc to Oracle Corp. He’s had a number of roles, including head of the performance team, JRockit Real Time evangelist and most current QA architect. He has also been working with the SPEC organisation, and was a part of the team that developed SPEC-JVM 2008. He is one of our experts at JRockit Real Time and low latency systems.

He introduces himself like this:

“Hello from JRockit land

This is an opening of this blog, so let me start out with very few lines about myself.

My name is Stefan Särne (with a weird Swedish spelling as you can see). And as follows that I am from Sweden, where we eat Lutefisk, where the polar bears walk the streets and the mosquitoes have fur.”

I hope that you will find Stefans, and all our coming, blog posts helpful and enjoyable.

September 11, 2008

Repost: Tips and tricks for dealing with a fragmented Java heap

Originally posted in December 2007, reposted on request. The problem described here is generic and applies to all JVMs using mark-n-sweep or similar GC algorithms.

Heap fragmentation occurs when a Java application allocates a mix of small and large objects that have different life times. The main negative effect of fragmentation is that long GC pause times caused by the JVM being forced to compact the Java heap. These long pause times are typically triggered when your Java program attempts to allocate a large object, such as an array.

As described in my previous blog entry on this topic, you can use JRockit Mission Control to find out how fragmented the heap is. But a fragmented heap is only a problem if it leads to long pause times (or an OutOfMemoryError). To find out the impact on pause times, you can run with the -Xverbose:gcpause command line flag, which will give you something like:

[INFO ][gcpause] old collection phase 1-0 pause time: 73.214054 ms, (start time: 15.807 s)
[INFO ][gcpause] (pause includes compaction: 1.029 ms (external), update ref: 1.532 ms)
[INFO ][gcpause] Threads waited for memory 66.612 ms starting at 17.568 s
[INFO ][gcpause] old collection phase 1-0 pause time: 66.449507 ms, (start time: 17.569 s)
[INFO ][gcpause] (pause includes compaction: 1.236 ms (internal), update ref: 1.488 ms)

The pauses in this example are clearly not a problem, but it can sometimes be much longer than this.

If you don't want to restart your JVM, you can enable this during runtime by running jrmcd <pid> verbosity set=gcpause=info. After you have the data you need, disable informational logs with jrcmd <pid> verbosity set=gcpause=error.

Or you can do a JRA recording (see the previous blog entry) and look in the GC details tab, where the time spent in compaction is clearly visible:

jra-compaction.PNG

Before we look into the possible strategies for dealing with fragmentation, it is crucial to understand what causes it. The first key observation is that fragmentation is caused by GC. When the JVM performs GC it will clear out dead objects. It's the act of removing these dead objects that creates the holes in the heap. Memory allocation only has an indirect impact, in that it can create a pattern in the heap that later leads to the GC fragmenting the heap.

A second key observation is that fragmentation is only a problem if you can't use the holes in the heap. As long as you only allocate small objects, it doesn't matter how fragmented the heap is.

With these two observations in mind, here are some tips:

1. Increase the heap size

Increasing the heap size will decrease the frequency of GCs. One benefit of this is that objects are more likely to be dead than if GCs are very frequent, and if more objects are dead then there will be fewer live objects around that can contribute to create holes. In other words, the heap holes will on average be larger, which implies less fragmentation. Also, if GCs are less frequent, you can possible afford longer pause times since the impact of GC on throughput will be lower. Be aware that increasing the heap size can cause a slight increase in pause times.

A special case is to run with an infinitely large heap and never GC, which will of course avoid fragmentation completely.

2. Use a generational GC

Running JRockit with -Xgc:gencon or -Xgc:genpar will enable the use of a nursery or young space. The nursery will store recently allocated objects and when it is full a nursery GC will be performed, in which objects that are still alive will be moved to the old space. Since all objects that survive are (eventually) moved to the old space, the nursery will never be fragmented. And fragmentation of the old space will happen much more slowly since objects moved there will on average survive for a long time. Also, since the old space will fill up less rapidly, fragmentation-causing old space GCs will be less frequent.

A common strategy for avoiding the cost of old space GCs (often called "full GCs") is to configure your nursery size so that almost all objects die before they reach the old space. If you do this carefully, you can postpone old space GCs for a very long time. I've seen some installations where the app has been configured to avoid old space GCs for a full day, after which it is restarted to force creation of a "clean" heap. This may be more frequent among non-JRockit users, since our compaction is fairly efficent and the pause times tend to be acceptable. One word of warning here: This strategy is not guaranteed to avoid full GCs, since that depends on the load on your application, exact heap layout etc, so don't rely on it too much and configure it with a large safety margin.

3. Tune compaction parameters

The default behavior of JRockit is to analyze the fragmentation of the heap and do a little bit of compaction every old space GC cycle. The proportion of the heap that it decides to defragment is called the compaction ratio which is typically stated as a percentage of the heap size, where a common figure would be perhaps 5%. If your application causes a lot of fragmentation, you can configure this ratio manually which gives you the ability to create a balance of power between the GC and your memory-hungry Java program. You can try with -XXcompactratio=10 or so to start with. A high number will lead to longer pause times, but also means that the JVM will be able to cope with higher fragmentation.

If you want to do advanced tuning, look in the JRockit reference guide for parameters that impact compaction. Two examples are -XXinternalcompactratio and -XXexternalcompaction.

4. Don't allocate memory

Ok, so it's time to look at what you can do in your Java code. The most obvious tip is avoid memory allocation. This will have direct impact on both the frequency of GCs and indirectly on the GC pause time, since less objects will be alive at the time of a GC. You can use the Memory Leak Detector to analyze your application's allocation pattern and trace down excessive allocation to where in your source code it occurs. See Marcus Hirt's blog entry on this subject for tips.

5. Avoid allocating large objects

Arrays and other large objects are always the biggest culprit when it comes to fragmentation. They cause the heap to fill up quickly, leading to frequent GCs, they create irregular patterns in the heap and they request big contiguous chunks of memory on the heap at allocation time, which can be impossible for the JVM to fulfill without first doing compaction. To avoid excessive allocation of large objects, think twice before copying arrays etc. All code involving string processing (char arrays), XML, I/O (byte arrays) etc is a target for optimization in this area. Again, the Memory Leak Detector is a very powerful tool for analyzing this.

6. Allocate objects with similar lifespan in chunks

This is my last tip, and it is a bit esoteric so please bear with me... The idea is that any larger operation can decrease its impact on fragmentation by allocating the memory it needs in a chunk and then keep it alive until the operation is complete. Consider a J2EE transaction such as a servlet request. When you start this request, you can have one metaobject created that allcates most or all of the objects that you need to process that particular request. Since these allocations will all be performed by a single thread and very closely spaced in time, they will typically end up stored as a contiguous block in the Java heap. If you keep all these objects alive until the transaction are done, they will all become subject for GC at the same time, and cleared as dead objects during the same GC cycle. Ergo, less fragmentation. So nulling out objects prematurely to decrease live data may not be the best in the long run.

Final words

That's it for this time... I hope you found this useful! Don't hestitate to ask if you found something unclear. Keep up the good coding!

Repost: How fragmented is my Java heap?

Originally posted in December 2007, reposted on request. The problem described here is generic and applies to all JVMs using mark-n-sweep or similar GC algorithms.

JRockit Mission Control is now free for development and evaluation, you can download it here.

One major cause for long GC pause times is heap fragmentation. How problematic this for an application depends on its allocation pattern. The worst possible case is an application that allocates a mix of objects with very different sizes and lifetimes. After the application has been running for a while, the Java heap will be fragmented by lots of long lived Java objects spread out across the heap. There may be plenty of free space available, but no large block of contiguous free memory. When the application then attempts to allocate a large object such as an array, it is unable to find room to store it. The result will be a long GC pause while the heap is compacted.

If you suspect you have this issue with your application, the first step is to try to find out exactly how fragmented the heap is. One simple way of doing this is by using the JRockit Runtime Analyzer. Here's an example:

1. Start a Java application on your workstation
2. Start up JRockit Mission Control using the Start menu icon in Windows or the $JR_HOME/bin/jrmc executable
3. Locate the process you want to analyze, right-click and select to start a JRA recording.

start-jra.PNG

4. Select recording time (here 2 minutes) and start the recording

jra-wizard.PNG

5. After the recording has finished, it will be opened in the JRMC GUI. Select the Heap tab. Heap fragmentation is displayed in black in the Heap Contents pie chart.

jra-heap.PNG

The application in this example is well behaved and shows only 11% fragmentation - well within acceptable limits. I would start getting concerned if it went above 30%, and more if it continued to increase. Another warning sign is if the free memory distribution (pie chart on the right) contains a very large proportion of smaller free blocks.