Can you explain how Java was chosen for your trading application? Also, why were you unable to test it properly?
The application was tested in an environment that's a lot like production, except that we had substantially fewer cores than an exchange running the same number of matching engines, so the incoming ticks were a bit less bursty. That burstiness was important in this instance. A big reason for the differences between the production environment and the test environment was the cost of hardware.
No criticism, as I've only read others' accounts, but that sounds out of character.
What's "out of character" (nice euphemism!) is adopting state of the art automatic garbage collection technology, writing in a language that makes actual garbage collection practically unavoidable, and then expecting that garbage collection doesn't happen or happens accordingly to arbitrary expectations. The JVM is clearly inappropriate technology if latency is important: it can perform well in common cases and with a reasonable level of tuning effort, but other options simply do not have the threat of GC pauses.
It's my fault that if you trade US equities based on old information you lose money?
Edit: Actually, I'm still not sure how to correctly measure GC pauses, other than from inside the application.