Archive for the ‘Java’ Category

Memory analysis with Eclipse 3.5

June 12th, 2009

Eclipse Galileo (3.5) will be released on June 24, 2009 and comes with a really good and easy-to-use JVM Memory Analyzer.

Memory chart

Memory chart

Here is a quick memory analysis walkthrough :

Creating a heap dump

You can dump the memory of a Java process anytime using jmap which is included in the JDK.

To ensure jmap is working for you, get your java process ID :
ps -Af | grep java

or, if you want to dump eclipse memory :
ps -Af | grep eclipse

Then ask jmap to output a memory summary :

jmap <pid>

Jmap output :
Attaching to process ID 356, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 1.5.0_16-133

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
(...)

If you get an error, take a look at the end of this post for a few tips.

Ok so jmap works for you. Now dump the complete memory in a file :
jmap -heap:format=b <pid>

There is now a file named heap.bin in your current directory.

Installing Memory Analyzer
Start Eclipse, use Help->Install new software… and select Memory Analyzer from the Galileo update site :

Installing Memory Analyzer

Installing Memory Analyzer

Opening the dump

Switch to Memory Analysis perspective

Perspectives : select Memory Analysis

Perspectives : select Memory Analysis


Use File->Open Head Dump… and select heap.bin
Memory summary

Memory summary

You can now digg into your application heap memory and ensure that no objects is using more memory than it should. Memory Analyzer also includes really nice features like an automatic leak search :

Leak suspects report

Leak suspects report

Have fun and catch the leaks :-)

jmap tips
If you have problems running jmap, try the following tips :

  • Be sure to use the jmap binary packaged with the JVM you are running : jmap from a Java 5 JDK will not be able to dump memory from a Java 6 VM : you’ll get this stacktrace :

    Attaching to process ID 704, please wait...
    Exception in thread "main" java.lang.RuntimeException: gHotSpotVMTypes was not initialized properly in the remote process; can not continue
    at sun.jvm.hotspot.HotSpotTypeDataBase.readVMTypes(HotSpotTypeDataBase.java:111)
    at sun.jvm.hotspot.HotSpotTypeDataBase.(HotSpotTypeDataBase.java:68)
    at sun.jvm.hotspot.MacOSXTypeDataBase.(MacOSXTypeDataBase.java:35)
    at sun.jvm.hotspot.bugspot.BugSpotAgent.setupVM(BugSpotAgent.java:560)
    at sun.jvm.hotspot.bugspot.BugSpotAgent.go(BugSpotAgent.java:481)
    at sun.jvm.hotspot.bugspot.BugSpotAgent.attach(BugSpotAgent.java:319)
    at sun.jvm.hotspot.tools.Tool.start(Tool.java:146)
    at sun.jvm.hotspot.tools.JMap.main(JMap.java:128)

  • jmap needs high system privileges. If you can’t attach to a java process with the following error :

    Attaching to process ID 704, please wait...
    attach: task_for_pid(704) failed (5)
    Error attaching to process: Error attaching to process, or no such process

    …, try to use sudo : sudo jmap <pid>. (See Ken Sipe's blog for additional information)

Debug a remote java application with Eclipse

June 12th, 2009

A developper should always be able to start an application in debug mode and run it step by step. While most IDE let you run and debug an application localy in one single click, debugging a remote application needs a few additionnal steps.

These steps are really simple but are usually a blocker for new Java developpers. This is what you need to do in order to run a JVM in debug mode and attach to it from Eclipse IDE :

Just add these options to the JVM :
-Xdebug
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000

This can be added to a launch script (Tomcat, custom application, …) or using a administration console (Glassfish, …). It’s often enough to look for the java command in your startup script.

The suspend switch makes the JVM wait for a debug connection before resuming application startup :

  • ‘y’ should be used when you have to catch a breakpoint right at the begining of your application
  • ‘n’ should be used when you want to be able run the application as usual and keep the possibility to connect at anytime. Note: running an application in debug mode is slower, even if you don’t attach to it.
  • Then In Eclipse, open and select your project, and use Debug configuration…

    Debug as...

    Debug as... Debug Configurations...

    Create a new debug configuration for a remote Java application :

    Remote Java Application

    Remote Java Application

    Change host value to your remote application host or keep ‘localhost’ if Eclipse and your application both run on the same machine and press Debug.

    Remote connection

    Remote connection

    Your application should immediately resume (if you used suspend=y) and you’ll be able to create breakpoints and use the debug perspective as usual.

    Note : I know there are tons of posts on this topic all across the internet, but I like to have it here too :-)

Apache Lucene sort tips

May 12th, 2009

The default search implementation of Apache Lucene returns results sorted by score (the most relevant result first), then by id (the oldest result first).

This behavior can be customized at query time with an additionnal Sort parameter .

TopFieldDocs Searcher#search(Query query, Filter filter, int n, Sort sort)

The Sort parameter specifies the fields or properties used for sorting. The default implementation is defined this way :

new Sort(new SortField[] { SortField.FIELD_SCORE, SortField.FIELD_DOC });

To change sorting, you just have to replace fields with the ones you want :

new Sort(new SortField[] {
SortField.FIELD_SCORE,
new SortField("field_1", SortField.STRING),
new SortField("field_2", SortField.STRING) });

This sounds simple, but will not work until the following conditions are met :

  • You have to specify the type parameter of SortField(String field, int type) to make Lucene find your field, even if this is normaly optional.
  • The sort fields must be indexed but not tokenized :

    document.add (new Field ("byNumber", Integer.toString(x), Field.Store.NO, Field.Index.NOT_ANALYZED));

  • The sort fields content must be plain text only. If only one single element has a special character or accent in one of the fields used for sorting, the whole search will return unsorted results.

ShareMedia 0.3.2 released

May 28th, 2008

ShareMedia is a photo manager based on Eclipse RCP. (open source / EPL)

Main features are :

  • Automatic file management (like in iTunes)
  • Sort and search using photos metadata
  • Standard and OpenGL photo viewers
  • Connect to Picasa, Jabber and Flickr (alpha) to share files
  • Ability to copy files between 2 accounts (Picasa/Picasa, Picasa/Flickr, Picasa/local files)
  • Plug-ins support (like all RCP applications)
  • much more…

This new release (0.3.2) includes :

  • Integrated intro content with tutorials and usefull links
  • SWT Animation Toolkit is now used to provide nice UI effects
  • Better error checking for password
  • Several bug fixes on the OpenGL viewer

For SWT/RCP developpers :
The Nebula Gallery Widget and the SAT toolkit where initially developed for this application so it is a good example on how they can be used.

Used libraries : SWT, RCP, Nebula widgets, LWJGL, DerbyDB, SmackAPI, Drew Noakes’s metadata Extractor, GData, FlickrAPI, SAT.

Screencasts :

Part 1 : Connect to a Picasa account, 3D and 2D fullscreen display

Part 2 : Download and upload photo, see metadata, create album and intelligent lists.

For the next release, I’m looking for some Java feedback. If you’re a Java developer and you already worked on the following topics, please drop a comment here.
- Writing EXIF / IPTC tags. (ShareMedia only have read support right now)
- Working with videos (creating thumbnails, playing in a SWT UI or OpenGL Canvas).

Thanks,

Some tools for unit testing (junit).

April 27th, 2008

JSF : Shale test

Database : HSQLDB (when using a compatible ORM tool, like hibernate)

LDAP : Apache DS (tutorial)

SMTP : Dumbster