Eclipse Memory Analyzer

Last time CodeRanch has a memory leak, a teammate ran Eclipse Memory Analyzer and I ran JVisual VM.  This time, I did both.  I took the heap dump as described here.  JVisual VM told me hibernate was using a ton of memory.

To run

To run Eclipse Memory Analyzer, I needed to launch Eclipse with more memory.  The default wasn’t enough to open the heap dump.  On Windows, I would edit the eclipse.ini file.  On Mac, I instead used a command line.  (I have read that it is supposed to be possible to edit the eclipse.ini too.  Didn’t work the once I tried it.)

./eclipse -vmargs -Xmx4g -XX:-UseGCOverheadLimit

(It was a production dump; just under 1 GB.)

What I learned

The Leak Suspects report was right on. It noted that the heap dump had three large Hibernate Session objects.  I was only expecting one.  We are using Entity Factory (which use Hibernate Session behind the scenes if using Hibernate JPA).  It turned out there was some code which intended to to cache the entity factory, but in fact didn’t for some nightly jobs we have.

try-with-resources and jdbc without sql injection

As I was on Oracle’s JDBC tutorial page, I noticed it was using a Statement rather than a PreparedStatement. I grumbled to myself about how this is teaching people to develop using SQL Injection and decided to Google for an example so I could tweet about it.

I was looking for an example of using try-with-resources automatic resource management using PreparedStatements. I searched on google for “try with resources jdbc”. This didn’t go well. I found a lot more of the same example including one from Martjin and Ben whom I respect. It is even that anyone’s example is bad. It is just oversimplified and implies that using createStatement is more common than using prepareStatement.

I then searched for “try with resources preparedstatement” to be more specific about it and found:

  • Informit does use a PreparedStatement but one without any binding variables.  Which means as an example, it isn’t much better.
  • JavaCodeGeeks does the same.
  • Someone on StackOverflow asked how best to do it and got an answer involving a nested try.  Which does work, but the nested try seem less readable than it needs to be.

I propose:


public List<String> query(Connection conn) throws SQLException {

List<String> list = new ArrayList<String>();

try (PreparedStatement stmt = createPreparedStatement(conn);  ResultSet rs = stmt.executeQuery()) {

while (rs.next()) {

list.add(rs.getString("name"));

}

}

return list;

}

private PreparedStatement createPreparedStatement(Connection conn) throws SQLException {

PreparedStatement ps = conn.prepareStatement(SQL);

ps.setString(1,  "test");

return ps;

}

The StackOverflow post proposes:

public List<String> query(Connection conn) throws SQLException {

List<String> list = new ArrayList<String>();

try (PreparedStatement stmt = conn.prepareStatement(SQL)) {

stmt.setString(1, "test");

try (ResultSet rs = stmt.executeQuery()) {

while (rs.next()) {

list.add(rs.getString("name"));

}

}

}

return list;

}

The StackOverflow answer is shorter.  I think the reason I like mine better is that is is easier to template out so the JDBC plumbing is only in a superclass.  Leaving us with

public List<String> query(Connection conn) throws SQLException {

List<String> list = new ArrayList<String>();

try (PreparedStatement stmt = createPreparedStatement(conn); ResultSet rs = stmt.executeQuery()) {

return processResultSet(rs);

}

return list;

}

The subclass then has two methods to implement:

  1. PreparedStatement createPreparedStatement(Connection conn)
  2. T processResultSet(ResultSet rs)  [templated to return type of subclass’ choosing]

Which approach do you like better?

no more sysdeo tomcat launcher on eclipse juno

I missed testing something big in my Eclipse Juno (4.2) review.  I tried out features and editors but didn’t actually start up my web app.  When I did that I, learned that Sysdeo doesn’t work with Juno.  And by that, I mean the icons don’t display and their website doesn’t say anything about Eclipse 4.2 support.  It didn’t say anything about Indigo (3.7) support either but Eclipse hadn’t changed enough to matter.

Which finally forced me to try out WTP’s server’s review.  It’s a lot like Rational Application Developer.  You have the Server view and right click to stop/start.  It’s fine, but I’ll miss the one click start a bit.

How to configure

  1. Add a new server runtime.
  2. Point it to already installed Tomcat 7 – /usr/local/apache-tomcat-7.0.14
  3. In server view, double click the server
  4. Change server location to “Use Tomcat installation” (we have CodeRanch configured to use the expanded war and be deployed to webapps automatically.)

How it works

It’s fine.  No complaints.  Not significantly harder than Sysdeo.  In fact, it is more similar to my work machine.  Sysdeo was a good ride for many years though.