Tuesday, May 5, 2015

Today I learned... DestroyJavaVM can cause JVM apps to hang instead of terminate

I have a long-running application that does some network IO (Oracle and SSH). It was taking longer than expected and it looked like it was done based on the logs. When I paused it to investigate, there was nothing active on the main thread, and all the threads were waiting.

I noticed DestroyJavaVM() in one of the threads, which I had never heard of (being new to JVM-land), and I also saw another thread that was stuck at an Oracle wait method, and a few other wait threads.

It turns out I forgot to dispose a couple of my resources before closing my application. When I fixed that, my application started terminating properly again.

Coming from C#, I've been spoiled by the using() block, which neatly cleans up any IDisposables. Really it's syntactic sugar for try{//do work}finally{disposableObject.Dispose()}.

In Scala I do the try/finally. I have read that there are ways to do something similar to C#'s using(), but they didn't seem as clean or intuitive to me, plus they'd need third-party libraries.

override def dispose(): Unit = { super.dispose() if (_dbConnection != null && !_dbConnection.isClosed) {
  _dbConnection.close()
}
_dbConnection = null 


I call this dispose() method in a finally block.

No comments:

Post a Comment