Picking Java's brains

Ever wondered what Java does with all that memory? Not so long ago you'd have to trigger a heap dump and then grovel over it with arcane tools.

But since the release of Java 1.5 (old news, I know, but still new to me) two wonderful utilities are included in the JDK:
  • jstat, which outputs statistics in a vmstat-like format (if you're familiar with Unix administration)
  • jmap, whose output is a bit friendlier.
jstat is very useful when you want to take several samples over a period of time to watch trends, but most people will want jmap, especially with the -heap option; this tells you the current (and maximum) sizes of various parts of the Java memory, along with how much of that memory is actually used.

jmap also supports other run modes; the most useful (at least to me) are:

-histo gives you a listing of the objects in the Java heap, listed by class. For each class, it tells you how many objects of that class are in the heap and how much memory they use. The listing is (at least on my system) in decreasing memory size order.

-permstat gives you a listing of the objects in the permanent generation; interesting (although unfortunately not really detailed enough) when something[tm] is eating your permgen space...

jmap can also be used to generate a heap dump, if you're so inclined. This can then be further inspected with jhat or similar tools.

And the best part? Well, there are two:
  1. These tools use the built-in instrumentation of the JVM, so you don't need to pass any funky commandline options (if you're running them on a local JVM, that is)
  2. They work on running processes!


More pom-parser fun

Almost forgot: pom-parser now parses the output of mvn dependency:tree instead of dependency:build-classpath. This means that we can (and do) construct separate compile and runtime classpaths!


Exciting developments in pom-parser

pom-parser.el (http://svn.grumblesmurf.org/svn/pom-el/trunk/) has undergone a major change: It now does all Maven operations asynchronously.

This has its advantages; most important is that Emacs will no longer hang for several seconds the first time you open a Java file in a project. The work to make this happen also makes it easier for me to add more Maven operations.

The first additional Maven operation is already in place: M-x pom-resolve-source-artifacts will ask Maven to download any source attachments it can find in your remote repositories; pom-set-jde-variables will then add those source artifacts to jde-sourcepath (if you pass it :include-dependency-sources t). It sure is nice to do C-c C-v C-y on a class name or variable and have the source for that class pop up...

There is a downside to this asynchronous goodness, though: You must wait for the message "POM parsing done." to appear in your minibuffer before doing anything that relies on the project variables being set. This particularly applies to compiling (as well as anything else that uses bsh).

I have tried various ways to make JDEE wait for Maven, but haven't figured out a working solution yet. Stay tuned, though!

Bug in JDEE with CVS emacs

If you're running CVS emacs and JDEE, you'll want to patch beanshell.el with the following:

--- jde/beanshell.el~ 2008-05-15 01:28:59.000000000 +0200
+++ jde/beanshell.el 2008-05-15 01:29:57.000000000 +0200
@@ -341,7 +341,7 @@

(insert output)
- 'exit status
+ 'exit (string-to-number status)
(if (string= "0" status)
(format "exited abnormally with code %s\n"

This avoids jde-compile falling over when the compilation is done (when running with debug-on-error).

Update: Turns out that parse-integer is not core Emacs; string-to-number, however, is.


Fixing emacs startup on Ubuntu Hardy (and Debian?)

Real quick: During emacs startup you may get messages in your *Messages* buffer saying "Error while loading file /etc/emacs/site-start.d/xxx.el". Most likely this is because that file includes a form (symbol-name flavor). Fix it to say (symbol-name debian-emacs-flavor) instead, and emacs will be much happier.

Noticed on Ubuntu Hardy with the emacs-snapshot package; I don't know if it affects any other distributions/versions.

Revisiting Maven + JDEE

I admit it, I've been an apostate. I have been seduced by the flashy pointclickiness of Eclipse, and have thus neglected my beloved Emacs (for Java coding, that is; I would never abandon the glory that is Emacs for reading news and mail, and for editing anything but Java).

However, recently I've come to feel dissatisfied with my heathen idols, and sought to return to the blessed, ever-welcoming arms of Emacs.

At this juncture I must apologize to the people who have commented on (and helped with) pom-parser.el. You have been most foully neglected, but now updates have happened.

http://svn.grumblesmurf.org/svn/pom-el/trunk/ holds the latest, greatest version of the pom-parser; it now correctly deals with all extant versions of maven-dependency-plugin, and adds the correct bits to jde-sourcepath.

Still to come: Separate runtime/compiletime classpaths; we need the runtime classpath to have completion work correctly, but should compile with the compiletime classpath in order to avoid relying on runtime dependencies in our code.