JDBC StackOverflowError on connection close
Running vertica 9.0.0-2 using latest JDBC driver 9.0.x with Java 8.
We get a connection from our tomcat pool, we perform a number of operations ending with two batch inserts followed by a commit (batches are fairly small first < 100, second < 1000). Then on closing the connection to add back to connection pool we get the following stack overflow exception.
Have tried reproducing on our test system, but have been unable to. However on our production system with the same data set it was very repeatable.
Exception in thread "Thread-4" java.lang.StackOverflowError
at com.vertica.core.VConnection.getStreamingBatchInsert(Unknown Source)
at com.vertica.jdbc.VerticaStatementSharedImpl.validateClearBatch(Unknown Source)
at com.vertica.jdbc.VerticaJdbc4PreparedStatementImpl.clearBatch(Unknown Source)
at com.vertica.jdbc.common.SPreparedStatement.close(Unknown Source)
at com.vertica.jdbc.common.SStatement.checkIfOpen(Unknown Source)
at com.vertica.jdbc.common.SPreparedStatement.clearBatch(Unknown Source)
at com.vertica.jdbc.VerticaJdbc4PreparedStatementImpl.clearBatch(Unknown Source)
at com.vertica.jdbc.common.SPreparedStatement.close(Unknown Source)
at com.vertica.jdbc.common.SStatement.checkIfOpen(Unknown Source)
.... repeats ...
Comments
Hi,
I wonder if increasing the size of the stack for each thread in the Tomcat JVM would help?
See:
http://www.tomcatexpert.com/blog/2011/11/22/performance-tuning-jvm-running-tomcat
Check the -Xss option.
A StackOverflowError is simply signals that there is no more memory available. It extends the VirtualMachineError class, which indicates that the JVM (Java Virtual Machine) is broken, or it has run out of resources and cannot operate. The common cause for a stackoverflow is a bad recursive call. Typically, this is caused when your recursive functions doesn't have the correct termination condition, so it ends up calling itself forever. Another cause is allocating a large amount of memory on the stack where using the heap would be more appropriate.
Here's an example:
public class Overflow {
public static final void main(String[] args) {
main(args);
}
}
That function calls itself repeatedly with no termination condition. Consequently, the stack fills up because each call has to push a return address on the stack, but the return addresses are never popped off the stack because the function never returns, it just keeps calling itself.
If the stack is full you can't push, if you do you'll get stack overflow error. StackOverflowError is avoidable if recursive calls are bounded to prevent the aggregate total of incomplete in-memory calls (in bytes) from exceeding the stack size (in bytes).