Information Technologies • 1:07:14
What will you do with more than 4GB of memory available to your Java applications? The 64-bit environment is not only for servers anymore. You'll learn about migrating 32-bit Java applications to take full advantage of a 64-bit platform, and the performance implications of doing so. You will also learn about functionality available on the desktop and on the server. We'll discuss how the JVM optimizes your application and provide tips on programming practices that get the most from those optimizations.
Speakers: Victor Hernandez, Roger Hoover, Pratik Solanki
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Today we're going to be looking at Java SE6. If you were in the last session, you heard about Mustang. Mustang and Java SE6 are one and the same. We're going to be talking about what's new, the 64-bit JVM, and performance. We're from the Java Virtual Machine team. Normally we're down very deep, down, down, below your application. You don't hear much from us unless things go wrong.
But every 12 months or so, we crawl out of our holes and tell you what's new in the virtual machine world. So today, I'd like to... fill you in enough so that you can answer the following questions. So, Java SE 6, what is it? What's new? And how is Apple enhancing the Java SE experience? Like you to know what the Java 64-bit virtual machine is, and I'd like you to know what some of the tools are that you can use to understand what your Java application is doing, and I'd like you to know and be able to answer just how does--.
[Transcript missing]
the Java C compiler, but it's been hard and it's not been standardized so that you can be assured that it's going to work through releases. And now through the efforts of the standards, the JSR group 199, and by the way if you want more information on these particular items, search for JSR 199 on the web, there's an API that allows you to use a compiler. And here's some code fragments that will give you a flavor of what it's like.
So on the top line here, I can ask the runtime environment for the system Java compiler and it returns a compiler object and I can take that compiler object and build up tasks which are like compile this file and compile that file. And then if I take the task and say get result on it, it will actually do the compilation and return the-- Yeah. --compiled result which I can then load through a class loader and then execute, call things through reflection.
Now this gives you a flavor of what it's like. It's still complicated. A Hello World example where you take a simple Hello World program as a Java's text string, compile it and execute it, it's about two pages of code. But it's a whole lot easier than it used to be. It's complicated because you have to set up.
You have to set up kind of file system objects to represent your text string as a file. You also have to set up paths so that you can get back from the compiler the stream of any error messages or warning messages. But in the end, you get the ability to take Java text inside your code and turn it into Java programs, Java methods that you can execute. And so the way this will change. The way this will change programming is that you can actually use Java as kind of a scripting language and take expressions or other program fragments, combine them with a context and compile them and execute them. Pretty powerful.
[Transcript missing]
People started using annotations for, well, there were the standard things that had been kind of there before, like deprecation and Java doc comments. But using the Java 5 APT processor for annotations turned out to be more difficult than anybody anticipated. So with Java 6, there's a pluggable annotation processing API where you can write plug-ins that don't have to do all of the work of, you know, searching through the entire program. You can actually just write plug-ins for the particular annotations that you're interested in. And you also have access to what the parse tree looks like. Pretty powerful stuff as well.
Scripting languages. There's a new scripting language access API. And just looking on the internet, I found references to almost every scripting language under the sun, including AppleScript, that people are working on using this API to plug into Java. So that when we get some experience with scripting languages, you'll have much easier access to JavaScript and a zillion other scripting languages.
And lastly, I want to talk about pre-verified class files. This doesn't change the language so much in terms of how you use it, but it does have some interesting things that you should know about. Let me go into detail. What split class file verification is, is that in Java 5 and before, when you load a class into the virtual machine, it has to verify the bytecodes to make sure that you're not doing something that's either unsafe or malicious that would harm the virtual machine, or give you access to things your program isn't supposed to have access to. And there's a cost involved in executing that verification. In order to make loading of classes and execution startup time faster, what Java 6 has is it's split between a compile time phase and a runtime phase. At compile time, the Java C compiler in Java 6 now compiles.
It compiles stack map attributes that tell in the bytecodes at given points what can be on the stack at any given point in terms of what type of objects. And the reason why this allows us to increase speed and still maintain security is that these stack maps are kind of hard to compute, but we can quickly verify them at runtime. So improved startup time, Sun is claiming 50% faster verification time.
We haven't timed it ourselves. The downside of this is that Java 6 has a new class file format. So if you're distributing class files that are going to run on earlier virtual machines, you need to use the dash target options to create class files that will run on those earlier virtual machines, and they won't have the split class file verification.
Okay, library support. A few new features that come from down deep in the virtual machine. Something that people have been asking for for ages is now here, the ability to find out how much free disk space is on the machine. There's some faster zip and jar file access routines, which speed up things all over a network file system. So if you're remote executing over the network, you'll notice some speed differences there.
There are a bunch of new concurrent classes. So if you're doing multi-threaded programming and you've been using the concurrent classes, well, if you haven't been using the concurrent classes, you should definitely check them out. But there are some new concurrent queues and several other classes, such as concurrent skip lists, if you're indexing data by key. Okay.
Okay, attach on demand. What is it? Well, let me take you back to Java 5 and talk about what we didn't have there. In Java 5, you saw a bunch of new monitoring tools, but you had to start up your program with a special flag in order to turn on the monitoring tool.
Now, for a server application, such as something that's been running in production, you didn't turn those on because there was a cost penalty. And by the time you realized that there was something going on, it had been running for a day, and there was no way to figure out how it was going on because you forgot the flag.
And you wouldn't have put it on in the first place because it's a production environment and it was costing you performance. So in Java 6, we introduce attach on demand. And this is a new protocol. This is a new protocol inside of the virtual machine that allows a tool to talk to the virtual machine. And it doesn't cost you anything until you use it.
And when you do use it, the tool will send a signal to the virtual machine, interrupt it for a moment, and then send it one of several commands that it knows about in order to execute and fire up the tool. So it supports the Java lang instrument and JVMTI tool interface. And several other of these tools that can now talk to the virtual machine. And as I said before, great for a server environment because you can run in production mode, yet when something seems weird, you can check it out. So let's go ahead and check it out.
something that people have been asking for for a long time, they install an experimental version of the virtual machine, and they go to the command line and they type Java, and they get the standard official version that's installed on Mac OS, and they want to be able to test it out from the command line. Well, we now allow you to change the command line execution via the Java preferences pane. So this is the Java preferences tool in Java 6.
It looks pretty much like the Java 5 one, but if you change the setting at the top of the list of the... So, the JVM version that's specified for applications, it also changes it on the command line. Note that applications in their plist encoding can specify which versions of Java that they need and must have to execute, and so they pick the first acceptable version on this list, but the command line will always pick the top list. So, here I've set it to Java 6. So with my command line now set to run Java 6, I want to give you some examples of some new features that you can use for monitoring and measuring under Java 6.
The jhat command is a new heap analysis tool, and I'll give you an example of that. The JMAP command, which was in Java 5, has some new options. Finalizer Info tells you things going on in finalization. And the dump option works with the Jhat command. We'll talk about that. I'll show you an example.
JConsole is new and improved. I'll run through some examples there. JInfo, and I'll show you that. And DTrace, later on in the talk, one of my colleagues will tell you about how DTrace support works in Java in the Hotspot virtual machine. JConsole is new and improved. I'll run through some examples there. JInfo, and I'll show you that.
And DTrace, later on in the talk, one of my colleagues will tell you about how DTrace support works in Java in the Hotspot virtual machine. For now, we're limited to examining processes on the same machine. We do not have the Solaris-only right now capability to examine processes on another machine.
So, JInfo is a tool that you give it a process ID. We'll tell you all of the properties of the Java process that it is running with. So, for example, if you're not finding a class in a running application and you want to figure out... Excuse me. You want to figure out which class path you executed the command with? Well, you can do that by simply examining the process with JINFO. It will also tell you, for example, which garbage collector flags and other VM flags you ran the application with. JMAP is a tool that tells you what's going on in the virtual memory system of the garbage collected heap inside of Java.
JSTACK is a command that will tell you what stack trace for each threads For each thread, what is the stack trace of the running application? So it just takes a snapshot of what it's doing. So if it's not making any progress, you can figure out what the threads are and what state they're in.
JSTAT is kind of a catch-all command that has a lot of options. If you use dash options, you'll get a list of them. Here's the list for Mac OS X. And I've given you two examples, one of looking at the classes that have been loaded in the application that's running, as well as what the compiler is compiling and how many things it's compiled so far, the just-in-time compiler.
Now, JMAP-Dump is new in Java 6, and it will take an existing running Java application and make a snapshot of the heap of that process. So here I've directed... Here I've directed the JMAP command to dump this information into a file called java2d.bin, since I'm examining the Java 2D demo.
So it creates this file, and then I use the new JHAT application, monitoring application, and it creates a web server that shows the heap analysis of the information that's in this dump. So if I type the JHAT command and give it this file that I just created, it tells me that it's reading a bunch of stuff, and then at the bottom it says, started HTTP server on port 7000.
So now I go over to Safari and load up localhost 7000, and lo and behold, here's a web page that describes every package that's being used in the application, and inside each package, all of the classes. And if I click on each of these classes, it'll tell me information about that.
And what I want to focus on is at the bottom of this page, you'll see it says other queries, and one of those queries is the peep histogram. So I'm going to go over to Safari, and I'm going to load up localhost 7000, and lo and behold, here's a web page that describes every package that's being used in the application.
One important thing you can do here, if you're trying to figure out where all your memory is going, is to click on this, and it gives you an ordered list by the total amount of storage used of objects of each class in your system, in your running application. So if I see something high up on the list that's way more objects than I'm expecting, chances are I have a leak in my system, and I'm hanging on to a bunch of objects that I really shouldn't be.
JConsole is new and improved in Java 6. It was in Java 5, but now it's an official tool that's part of Java 6, and it has some additional capabilities. So let's focus in on this. When I started it, it gives me a list of what JPS would have given me, a list of the running Java processes.
So let's click on the java2d.jar, and it gives me this interactive display showing me memory usage, threads, CPU runtime, a bunch of information. And I can click on the bar on the top and get more detailed information further. For example, here are threads. It shows me the high watermark of the maximum number of threads I've executed so far. And it also gives me down on the bottom part a list of all of those threads.
And if I click on a given one, it will give me specific information about what that thread is doing. So it's a very powerful interactive tool for understanding where your Java application may be using more resources than necessary, or where it's getting lost, or any number of issues that you may encounter when you're trying to make your application run as most efficiently as possible.
A note about crash reporter logs. All through the past, we've had two separate logs when Java goes wrong and crashes. There's been a crash reporter log and a native crash log, and we always have this little dialogue when people submit bugs. If they don't submit both of the logs, then we have to go back and ask them for the other one.
Well, in Leopard, we've fixed this, and we've managed to get all of the information in the crash reporter log. But if you're submitting bugs for Tiger and before, be sure to include both of those logs, as always. And importantly, we want to make this Java 6 release as stable as our Java 5 release and better. So when you do encounter problems in our developer previews or on the seed that's on the Leopard disk, send them to us, bugreporter.apple.com. So let me introduce Victor Hernandez. He's going to tell you about the 64-bit virtual machine.
I'm Victor Hernandez. I also work on the Java VM for Mac OS X. The last couple years, we've heard a lot of feedback about how a lot of you customers want a 64-bit JVM for Mac OS X. Well, sure enough, this year, we actually have the hardware and the software support available for you to be able to run your application in a 64-bit Java VM.
So, what do you need to know about that, the 64-bit Java VM? Well, if you've been to the other 64-bit sessions here at WWDC, you found out that 64-bit environment means that pointers are now 64-bit. The native size of the pointer has increased from 32-bit to 64-bit. Okay, so what does that mean for Java? Well, what it means for your application is...
[Transcript missing]
Just like a year ago, you didn't have to do much to move from PowerPC to Intel, now you don't have to do much to move from 32-bit to 64-bit. In fact, transitioning your Java application to a 64-bit JVM is completely transparent. So if it's so easy, why should you actually care? Well, there's one issue that you need to know about, and it's a really big positive for some applications.
And that is the fact that now your application can run with a larger Java heap. Before in Mac OS X, in the 32-bit world, the maximum Java heap size was 2 gigabytes. Some of you might actually remember some of the earliest releases of Mac OS X, that actually this limit was actually even lower.
I can't remember what the exact number was, but we actually did some futzing around defragmenting virtual memory to actually get that number to be around 2 gigabytes. Well, to incorporate... Increase that even more would create some problems in virtual memory, and we could never get anything more than 4 gigabytes anyways.
Well now, with the 64-bit JVM, you're way beyond that 2-gigabyte limit. In fact, it's a huge number. I'm not even going to mention the number, because the real thing you need to know about is that you can use as much memory as... You can use a Java heap the size as large as the physical memory you have on your system. I'll be mentioning it in a little while. Why you should be doing that. You probably don't want to be using a Java heap any larger than that. But it's very cool.
So what does this mean for your application? Well, let's talk about what kind of applications could benefit from a larger Java heap. I think it falls into four different categories of applications. And all of these applications have in common that either they're using a lot of data coming off of disk, or they're creating a lot of data during the execution of the application themselves. So let's go through some of these.
How about something that processes a large amount of data coming from disk? Applications like gene sequencing do that sort of thing. Another good example is an enterprise application that's reading a lot, that's querying the database constantly. What about the situation where suddenly that application was able to cache the full database in memory, no longer having to add that query time to the latency of a transaction? The iTunes music store, for example. The iTunes music store, for example, could definitely fit.
Imagine if they had all their songs, all of the album art, all of that cached in memory, and then basically it's just that much faster. That's a really, really powerful situation to be in. Another example are scientific applications that do algorithmic computations of visualizations or simulation. Things like NASA and NOAA are doing. This is a good example where you might actually be starting off with a small amount of data, chugging through that data in such a way that you generate a lot more data, and then actually extract from them some sort of results, then you write to disk.
The last one actually is a set of applications that I haven't actually seen written very much, especially not in Java, where you're taking a large image data, a large image, and processing it and then writing it back to disk. I'm really looking forward to seeing those sorts of applications written for the Mac, maybe even in Java using 64-bit JVM. So these are the hypothetical lists.
I actually want to get really excited about running real-world applications on the JVMs that we develop here at Apple. And so I went fishing around the Internet. The application that we found that was really cool to use was GeneSpring GX. It's from Agilent Technologies. And all I know about it is it does gene sequencing. How many people here know what gene sequencing is? All right.
So this is a really cool application. It's a really cool application. It's a very, really cool application. It's really, really cool. It's very, very cool. It's very, very cool. It's a really, really cool application. I did not have access to it. It's not even amongst the people holding up their hand at all. This application is a complete black box to me. All I really know about it and all I really care about that's really cool is that it uses -- it generates a whole bunch of data. It's a complete black box. And I was like, "Oh, my gosh.
It's a complete black box." So we loaded some data. We loaded some data. We ran an experiment. And immediately, it popped up this dialogue that said, "Oh, sorry. There's not enough memory." In fact, this experiment takes almost six gigs to run. Well, clearly, in a 32-bit world, that's not possible.
And I was like, "Sweet. We have a 64-bit Java VM. Let's try that." And sure enough, under our current Leopard Seed support, we were able to run this application. The experiment runs fine. The graphics looks great. Basically, the app just runs. And we expect that to be the case for your application running under Leopard.
Okay, so now you need to be asking yourself a few questions. I have described some of the nature of applications that could be using larger heap sizes, but does that apply to your application? Well, the first question you need to ask yourself if you need to move to a 64-bit JVM is, have you been encountering out-of-memory errors with your application? If you are, you probably, you know, you wouldn't be hitting them if you're using larger heap size.
But keep in mind that there is another reason, other than algorithmic complexity, as to why your application is hitting out-of-memory. It's obvious, but I still need to point it out. If you have a Java leak, a Java memory leak in the 32-bit world, you're still going to have it in 64-bits, and it's just going to take longer for you to find it.
So fix it before you actually move to 64-bits. There's another reason. So let's say your application doesn't hit an out-of-memory error. Why would you go to 64-bits? Well, what about the case where if you actually were to use more memory, you would actually be able to re-architect your application so it would actually scale better? A good example is something where you've split up tasks a bunch of different processes, and now you can think about moving all those processes into one process, farm them out to multiple threads, and just use a larger Java heap. That application will definitely be scaling a lot better.
But I do want to make the point that you should be approaching all of this conversion from 32-bit to 64-bit with not switching to 64-bit just for the hell of it, but actually convincing yourself that it's actually needed for your application. The default should be, you know, stick to what works for your application best.
And the reason that you shouldn't just move to 64-bit is because there's three things that you really need to consider that will actually change once you go from 32-bit to 64-bit. Three things you need to pay attention to. The first one is memory pressure. How much more memory are you using? Second one is the speed of your application.
Is your application just going to simply become faster? Marketing might want you to believe that. But we'll find out the details of that. You also need to know how much garbage collection overhead might change going from 32-bit to 64-bit. All right, so let's go into the first one of these. Memory pressure.
Well-- Pointers are now 64-bit. They're not 32-bit. So your application, every single object reference you have, every reference you have to a Java object is now twice as large. If you've been doing a good job of writing really good object-oriented programming, then you're going to have a lot of these references. If you've been to any of the other 64-bit sessions here at WWDC, a comment actually has been made that the memory pressure is really not that significant going from 32-bit to 64-bit. Because most real-world applications, their data structures are not full of pointers.
Well, with Java, that's different, and we have to make the point here. In the worst case, an array of objects is going to be twice as large. Most typical objects, that's not going to be the case, but they are going to be bigger simply because you're keeping track of the superclass and any sort of object that you have in your fields. It's going to be bigger.
So now that you know that the amount of Java heap that you're going to be using is going to be larger, keep in mind that you should still use the general rule of trying to use the smallest Java heap possible anyways. Measure, increase at the given amount, but don't just increase it two times or three times just because you're moving a 64-bit.
Also, this is where I want to talk about the fact that if you're using a large enough Java heap and you actually are using a heap larger than your physical memory, because of the nature of the JVM, we're actually garbage collecting the full heap at a given point in time. And if we actually can't fit that all into memory, you're going to be experiencing a lot of paging, and it's not a really good idea.
If your computation requires it, then go ahead, but do try to avoid that. Especially in the case where if you're developing on a system with 16 gigs, sweet, your application runs, but be aware that your users might not have that amount of memory, and you need to handle that situation accordingly.
Especially in the case where if you're developing on a system with 16GB suite your application runs, but be aware that your users might not have that amount of memory and you need to handle that situation accordingly. Especially in the case where if you're developing on a system with 16GB suite your application runs, but be aware that your users might not have that amount of memory and you need to handle that situation accordingly.
[Transcript missing]
Okay, the third thing you need to be aware about the change in performance of your application is the cost of garbage collection. If you use a larger Java heap, it will take longer to collect it. You will experience longer pause times. So how can you change your application? You can't just use less memory.
Well, one of the things that you need to realize is that with the new Intel Macs, especially the Mac Pro we announced on Monday, we are talking about systems that now have four cores. You actually probably do have extra CPU available to you for doing a lot of asynchronous computations for your garbage collection.
And we've been shipping since Java 4 alternative garbage collection algorithms outside of the default one, the synchronous mark sweep, that until now, it might have been somewhat compelling to use. But now when you have all these CPUs, it really, really can actually make a huge difference. Specifically, so there's two of them. There's the parallel garbage collector. There's the concurrent mark sweep garbage collector.
And I have the, you can read what the flags are right there. One of the things to point out about the concurrent mark sweep is that this one actually runs asynchronously to your application. So it takes a little bit of CPU all the time. And therefore minimizing the actual latency at the time when your application is only doing garbage collection. So this is another way of you can improve the garbage collection performance while you're running.
Okay, so I've talked about a lot of stuff, but being the cynic that I am, I really want to actually show you our 64-bit JVM in action. I don't have anything too spiffy. Let's see. Where are we? Hmm. Can we get the demo machine up? All right, I'll give it a second or two. Let's see, what can I talk about? Well, I'm just going to continue with the slides and then see if I can... Try... Yeah, let's just go with the slides then.
Okay, so what was I running that on? Well, you don't know what I was running. But what I was running that on is our just announced Mac Pro. Well this is exactly the sort of configuration that we will be supporting a 64-bit JVM on. We'll be shipping this with Mac OS X Leopard.
It'll be running on all of our 64-bit enabled Intel Macs, and it will be available only in Java SC6. What can you expect to be able to run in the lab on the Leopard seed or on your own Mac Pro when you buy it and install the Leopard seed? Basically, you should be able to run... You should be able to run an application as complicated as GeneSpring.
The graphics stack works, GUI works, networking works, just about everything works. We just barely got this thing up and running, but we've been really excited about how much actually we've been able to get working, and we're excited to see what you're able to get up and running and give us feedback on what's left to do.
One thing that we do know is a lot of the tools that Roger mentioned in the previous part, JConsole itself does work, but a lot of the other tools like JStack and JHeap analysis tool, those aren't there yet, but they will be ready by the time we ship Leopard.
Okay. And how do you actually turn on 64-bit in your application? It really is as transparent as I was mentioning before. You need to add one flag, and one flag only. It's the minus D64 flag on the command line. Once you've done that, you will just get the same old default heap size, but you're actually able to create larger heaps. So just change your heap size with minus XMS or minus XMX, and that's it.
Well, almost it. Just like last year, if you're not a pure Java application, you do need to do more work. You actually probably do need to pay attention to the tips and tricks mentioned in the other 64-bit sessions. Oh, there we go. All right. Let me go over here. I just want to actually prove that we actually had this thing running. Those of you that haven't been down to the lab, you can see here's our 32-bit JVM. No big deal.
It's an obvious hello world. It's not that exciting. But right here, you can actually see that we're running a JVM. We're running with a 64-bit JVM. All right. Let me up the ante just a tiny, tiny bit. and actually show you a large heap size. So what's big enough? Let's go with... 5000 meg and a maximum heap size of what? 10 gigs. And sure enough, that works. Oh. Oh, yeah, sorry. That's not completely right.
And as you can see, and as you're perfectly aware of, if I had run this without... That it actually says that it's an invalid initial heap size. So sure enough, this works. No big deal. I was thinking of showing you something that would show you the different GC characteristics of an application. But the reality is that all the GC behavior is dependent on what kind of application you have. So I don't want to show you something that contrived. What I do want to point out is one of the other messages that I gave you earlier.
That it actually says that it's an invalid initial heap size. So sure enough, this works. No big deal. I was thinking of showing you something that would show you the different GC characteristics of an application. So here I'm bringing up Java 2 demo. This is the 32-bit version.
I'm just going to go immediately to the composite frame. And I'm going to launch-- JConsole, the same application that Roger was mentioning before. And I'm going to go ahead and connect to... Java 2 demo. And then while I'm doing that, let me get the 64-bit version. And you'll see that I'm running with the exact same heap size.
That I was in the 32-bit version. Okay, so I got that running. Let me go to composite. And let me increase the animation delay on both of these. So that we create a lot of objects. Let me get this going. There it goes. That's hung. All right. So as you can see, there's the second-- Java 2 demo.
So we got the two of them running side by side. I got the animation delay up. This is the amount of memory actually being used by the 32-bit one. And over here we have the 64-bit one, the JConsole for it running. Let me show you these side by side.
One thing to point out here actually that is really powerful is the JConsole is running in 32-bit, and it's introspecting a 64-bit application. You can do this totally seamlessly on the Mac, have 32-bit and 64-bit applications side-by-side, and have them communicating with each other. Just like I said, the other tools don't work yet, but we will have them running as well.
Here's my point. The exact same application, the exact same code, the exact same Java heap, and just by running in the 32-bit, we're having about a steady state that's well below 10 gigabytes. It says in really small right there, 7.3 megs of memory used, and that's Java memory. And then over here, we have well above 10 megs, around 13 megs being used with the exact same application. So watch out if you're trying to deploy a lot of applications on the same system. Your memory pressure is going up. Let me go back to slides.
Okay, well actually that's about it. I hope you, I'm really excited to see what kind of new applications you're going to be bringing to the Java on Mac OS X. Do let us know what runs, what doesn't run. We'll be at the lab with 64-bit machines available to you, so we want to see your application running. And thank you very much. I'll bring up Pratik Solanki now to talk about a bunch of new tools. Thank you.
[Transcript missing]
So I'm going to give you a very simple example script. And there's a detrace session tomorrow at 10:15, so I highly encourage you to go see that. But here's a very simple example. It's sort of like a simple contrived example. What if I wanted to find out what processes were opening which files on my system? So I just want to know what files are being opened on my system and what process is opening it.
Well, I'd write a very simple script that looks something like this. And what is this doing? So the first line over there, all that it's telling detrace is, I'm interested in the open syscall. Fire this probe when the open syscall is entered. And what happens when the probe gets fired? Well, you're just going to do a printf, a simple printf that says, what's the name of the executable? Exec name out there is a built-in detrace variable. That's the name of the executable.
And what's important in the second part is arg0. arg0 is the first argument to open. And if you look at the man page, that's nothing but the path to the file. So that's a simple detrace script. You run it on your Mac OS X Leopard system on the seed that you get right now.
And you'll see output like this. So I ran it on my system. And while I was running this script, I was actually doing a cat of one of my favorite files, the java.crash.log file. I get that a lot. So I do open that a lot. So I was doing a cat of that. And you can see cat's opening up a bunch of to start up. And you can see it opened up the java.crash.log towards the end. And the last two lines over there is basically spotlight hard at work.
So that was DTrace. That was a very simple DTrace, like a two-slide overview of what DTrace is. How is that important to you? What do you need to worry about? Why is DTrace important to you as Java developers? Well, in Mustang or in Java SE 6, we have built-in support for DTrace, which means that the JVM exposes certain probe points. It exposes a variety of probe points, which are kind of divided into two categories.
In DTrace lingo, they're called providers. So what are these probe points, and what are these providers? Well, the first one is the hotspot provider. And this is an example of some of the probes it gives you. It's basically giving you access to VM-level probes. You know, all the VM internals, you know, GC start, GCN, monitor, enter, exit, class loading, unloading, thread start.
So all these VM-level, low-level things, it's kind of what the hotspot provider is giving you access to. So you can write your DTrace script to, you know, for listening to these probe events. The second one is a very straightforward one. It's the Hotspot JNI provider. It's very simple. It's just an entry and return probe point for each and every JNI method. So for any JNI method, just put a dash entry and dash return, and that's your detrace probe point.
So, you know, here's a very simple example that I wrote up. And this is basically, you know, what I'm going to show here is one of the most frequently asked questions in the Java world is you always want to know how much time the garbage collector is taking.
You know, your app's running slow. You want to figure out, hey, is the GC taking too much time or what's going on? So here's a very simple DTRA script that you might write to figure that out. And let me explain to you what this, you know, block of code's doing.
The first thing is, you know, the probe points, the probe entry points. Hotspot, because it's a hotspot probe. GC begin, GC end, you know, straightforward, the name of the entry points. The $1 over here, what is the $1? Well, $1 is nothing but the first argument to your script.
And you need that because what you typically pass to the script is the PID, or the process ID of your Java application. So that DTRAs know which process you're interested in. So, hotspot $1, colon, colon, colon. And GC begin. Why the three colons? Well, you know, you've got to go to the DTRA stock to find that out.
What do you do when GC starts? All you're doing over here, all I'm doing is just saving the timestamp. I'm just saving the timestamp in a start variable, and when GC ends, I'm going to calculate the total time that it took. So I'm going to calculate the current timestamp minus what I saved, and I'm just converting that into milliseconds because timestamp is in nanoseconds.
And then I just print it out. Very simple script. I can run it against a Java process. And just like as Roger talked about, attach on demand, where you don't need to start the Java VM with particular arguments in order to use JConsole now, it's the same thing with DTrace.
You really don't need to start your Java VM with any, your Java program with any particular arguments. You could run the script on any running Java process and, well, not any running Java process, the one that's using Java 6. But you could run the script without having to start the VM with any special arguments. So what happens when you run the script on a Leopard system? Well, let me show you. If I can get to my demo machine. All right.
Okay, thank you. So I'm going to show you how DTrace works. I'm taking the Java 2D demo as an example application. Consider it your long-time running server process, if you will. So what you need to know is, let's see, you need the process ID of the, of your Java app. In this case, it's 365. And here I'm going to just run.
I'm just running the exact same script that I just showed you. I need to run DTRACE as root, so enter my secret password. And there you go. It just keeps printing as GC happens. As you move around, you'll see GC taking 500, 17, 12. It just keeps printing the amount of time that GC is taking. Well, all that's good. Let me just start off under the script, and let me tell you what I'm going to do over here.
So that was a very simple example. It just printed out the amount of time that it took. But really, the power of DTRACE lies in the D language, or the D scripting language. And there's a lot of features to it, and one of the small features that I'm going to show you is that it allows you to kind of print out a nice little statistical distribution. So instead of seeing numbers scrolled by like 500, 12, 16, you may want to know, well, on average, how much is it taking? Or what's the statistical distribution? And that's the distribution of my GC times. And DTRACE lets you do that.
And DTRACE, in fact, from the script that I showed you, I just made one line change, and I'm running that script right now. And when I stop it, Here's what it's telling you. It's telling you, well, most of the garbage collections are taking somewhere between 8 and 16 milliseconds. So it's like in the time period that I had the script running, 13 GCs occurred that just took less than 16 milliseconds.
But there were a few that took more time. They took around between half a second to one second. So it's a better way of visualizing your data instead of just having standard printers. And DTRACE is very powerful and flexible in that way. So that's just my very simple demo on DTRACE and how it runs and what you can do with it. So let's go back to the slides.
I know what my next slide is, so let me just tell you what I was going to say. We have some caveats with DTrace. It's a new technology. Obviously, we've just started getting it to run on Mac OS X. In fact, the Leopard Seed that you have right now, the Java 6 on that Leopard Seed, it's not DTrace-enabled. So you can't really run the script that I showed you on your Leopard Seed.
But we will make it available come spring 2007 when Leopard ships. We will make DTrace support in Java enabled, and it will be running. And you would be able to run all those fun little, definitely the script that I showed you, and a lot of other scripts that you can find on the web. You should be able to run that.
So the next thing that I wanted to talk about after D-Trace was X-Ray. Again, how many people have heard about X-Ray or know about X-Ray? Because it's been talked a lot at this conference. Yeah. So, okay, we're back. Let me just... You know, told you about the caveats. It's Java 6 only. Sorry, it's not available for Java 5. Okay, so let's move on to X-Ray. What's X-Ray? Well, you know, that's X-Ray. You've heard about it.
You've seen demos in Ted Goldstein's talk. And there's actually a session on X-Ray today at 2 o'clock, so, you know, go for that. Check it out. It's a new tracing profiling tool, very GarageBand-like, where you can add, you know, different kinds of instruments and see how your app or how the system behaves with respect to all this, you know, this data that the instruments will gather for you.
The 64-bit environment is a great place to start. You'll learn about memory consumption, CPU consumption, file access, disk access, all these kinds of things you can trace in X-Ray. And again, why is that important to you as Java developers? Well, in Leopard, we'll have built-in support for Java. So in X-Ray, you would be able to profile and trace your Java applications.
And you could do thread tracing, memory tracing, and it'll be fully supported in Leopard. Unfortunately, it's not available in your developer seed right now. But we will have it available for Leopard. So here to give a small demo of X-Ray and how it works with Java, here's Lin Salameh.
I just want to show you a little demonstration of how X-Ray works with Java. If you've been to Francois' talk, you might have seen this before, but we thought we'd do it again. All right. So, let's see. So, we're going to start with the first one. Here's my X-ray application, and as you can see, we have all the instruments down here at the bottom. I'm going to drag up the Java thread instrument up here, and to start profiling, I'm going to press play.
And as usual, we're going to select the Java 2D demo and start profiling it. So the cool thing about X-Ray is that it allows you to see the results of your Java profiling at the same time that you're running your application. So I could, you know, here's my Java 2D demo launching up, and I could play around with it, you know, change colors a little bit, and then, you know, stop it.
As you can see, the results of my profiling, let me zoom in a little bit, shows me all the threads that have been running for a while. Threads that are green are threads that are running, and the yellow colors are threads that are waiting. Threads that are blocked are actually shown in red. I'm actually interested in the threads that are blocked, so let me scrub over to threads that are blocked.
And let's see right here where my main thread is blocked. And I'm going to click the info button to show me more information. And as you can see, I have all the names of the threads of that time slice and their priorities, whether they're daemon or not, and whether they're blocked. So I don't know if you can see this very well, but the main thread is actually blocked on App Class Loader. And for more detail, I can click the Extended Detail button right here, and I can see the stack trace of what's happening.
Other threads are actually running. And I can also scrub along and see here my event queue thread is actually--
[Transcript missing]
Okay, back to the slides. Okay, so that was how X-Ray works with Java. So those were the two new tools that we have for you in Leopard, you know, great new tools. I really encourage you to try them out once you get a hand on them, and it should make your life a lot easier.
So let's move on. Let's move on to performance, you know, numbers. I'm going to talk to you about the performance of the Java 6 VM that you have right now. We're going to go over, you know, we're going to go over some of the improvements that have been made in Java 6 as compared to J2SE 5. We're going to, you know, I'm going to explain to you what I'm measuring my performance benchmarks on, you know, what benchmarks I'm measuring.
And then we're going to look at some graphs that tell us, you know, how does Java 6 compare to J2SE 5 in terms of the performance. So let's move on to the client and server compilers and, you know, how does Java on Mac OS X compare to Java running on Windows.
So let's look at client performance. So what has happened in Java 6? Well, Sun's been busy. It's been hard at work. And some of the improvements that they've made in Java 6 in terms of the client compiler has made quite a bit of performance impact, in fact. So what they did was they changed the intermediate representation for the client compiler. They now use the SSA intermediate representation, which is static single assignment. That's what SSA stands for.
And it's a very powerful form of intermediate representation. In fact, that's what's being used in the server compiler, and it's being used in JVC 5 as well. And it lends itself to better optimization. So it's very powerful, and the client compiler is now using the SSA IR. Thanks to that, they've also added now a new register allocator in the client compiler.
It's a very simple register allocator. It's a linear scan, simple register allocator. It's certainly not something as complex as the one that you find in the server compiler, but it gets its job done, and it does bring in a good bang for the buck, so to speak. It does bring in a nice little performance boost.
Another important improvement that they've made is that the client compiler now makes use of SSE/SSE2 instruction set, which means that, going back to what Victor was talking about, how you may not see a big performance boost in long double performance between the 32-bit and the 64-bit world. This is one of the reasons. If you're using SSE/SSE2 instruction in the 32-bit world, you're already getting a lot of the 64-bit advantages.
You may not see a big boost over there when you move to 64-bit. The client compiler is using these instructions and it's helped it a lot. The server compiler was always fast. It was really very fast. In Java 6, it's doing more aggressive inlining. It's generally gotten better. There's some bug fixes, some tweaks. It's generally been improved over the last two years that Sun's been working on it.
Things are looking better in 1.6. So what's our system configuration? What are we using? I'm using a standard Intel iMac. It's got some extra RAM, and you can read everything over here. The thing to note over there is I'm using comparable versions on Tiger, Leopard, and Windows. And I'm using RDP4, because that's what you have on Leopard.
What are we measuring? I'm going to show you graphs that measure two benchmarks. One of them is the CIMARC benchmark. It's a numerical benchmark, computationally intensive benchmark. And the second one is a business logic benchmark, kind of to give a feel for what the real-world performance impact of Java 6 will be like. So let's dig in. First slide, we're going to compare Java 6 versus Java 5, and we're going to look at the client compiler. I'm going to look at CIMARC composite scores, so larger is better over here.
The bigger the number, the better the score, the faster the VM. This is how it looks. We've got two bars you see over there, and obviously, as you can see, Java 6 is better than Java 5. And in fact, Java 6 is about 18% faster than JVM 5 was. So straight out of the box, just by switching VMs, you're going to get a performance boost on your client compiler.
What about the server compiler? Well, the server compiler is also faster. It's not as fast as the client compiler, but it's also got a modest 4% gain. It's faster than J2SE 5. So across the board, you'll see a nice performance boost when you move from Java 5 to Java 6. If you look at our business logic benchmark to get a sense for the real-world performance, the bottom two bars that you see over there is Java 5 and Java 6 compared on the client compiler.
And again, the client compiler is about 17% faster in Java 6, but the server compiler really shines out here. In fact, the server compiler has gotten about 37% faster between Java 5 and Java 6, as you would expect. This is like a business logic benchmark, so it's a long-running app. Server compiler is definitely better suited for it, and it's quite fast.
Now we're going to look at performance numbers across all the three different OSes that I can install right now on my iMac. I can install Mac OS X Leopard, Mac OS X Tiger, and Windows XP using Boot Camp. So I'm going to show you SIMAC numbers across all three different OSes, and how does it look? Well, it's pretty comparable. All three OSes perform comparable.
In the past, we've had questions and reports that Java on Mac OS X is slower than Java on Windows. Well, no more. You give it the same hardware, and Java on Mac OS X performs just as well as Windows. You shouldn't see any performance degradations when switching OSes. This is a client compiler. Server compiler is the same. All three OSes are pretty identical in terms of performance.
64-bit. Victor just announced the 64-bit VM that we have right now as part of Java 6. How does it compare? I'm going to show you CIMAC again. These are the bars for the client compiler, the 32-bit client compiler. This is a numerical benchmark, so you expect the server compiler to do better. Sure enough, the 32-bit server compiler is better in most of these benchmarks.
What about 64-bit? How does it compare? The result's mixed. Sometimes it's a bit faster, sometimes not. I would like to add the caveat, though, that this is, as Victor said, we just got this running. We obviously haven't had any time for any kind of performance tuning. This is a beta Java 6, beta 64-bit support on a beta Leopard OS, so the final numbers will definitely look different than what you see over here. This is just to give you an idea of how the 64-bit VM performs.
So, in summary, what have we seen in all these wonderful little bar charts? We've seen that, you know, the performance of Java on Mac OS X and Windows is at par. It's not something you should concern yourself with. Java 6 is faster than J2SE 5, so, you know, I definitely encourage you guys to kind of go try it out and run your app and see how well it performs. The client compiler has received a significant boost, so you should see an improvement straight out of the box.
You know, the client compiler is the default, so you should see much faster performance. and 64-bit is not really for everyone. You really need to sit and look at your app and you need to see whether you need the extra memory. You need to run in a 64-bit environment before jumping and passing the minus 64 flag to your applications.
So that brings us to the end of our session. To quickly go over what we've talked today, we've talked about 64-bit support for Java on Leopard. There's a wealth of new tools that you're going to have in Leopard. You've got all your JMAP, JConsole, JInfo tools. You've got DTrace. You've got X-Ray. And something we didn't talk about in this session, but which Victor and Rick talked about in the previous session, you have Shark. Shark's been available on Tiger.
It's there on Leopard. You can use it for profiling and tracing your Java apps. Use it. Find your performance bottlenecks. Improve your applications. And Java 6, it's available right now. We announced DP5 on Tuesday. Go ahead, download it. Try it out on your Tiger systems. For Leopard, it's there on your developer seat that you got this week. Try it out. Give us your feedback. Bugreporter.apple.com. Mark that site. File bugs. Tell us about it. Tell us any issues, problems you run into.