После некоторой значительной игры с этим был другой код теста кода, который считывал метаданные, но не закрывал набор результатов. Теперь проблема ушла.
Моя теория состоит в следующем. Чтобы получить метаданные базы данных в MSSQL, вам необходимо подключиться к базе данных, отличной от текущей. Один из способов сделать это - изменить базы данных (в MSSQL есть команда use). Проблема с этим подходом заключается в том, что вы можете испортить транзакцию с текущим соединением и вызвать проблемы с многопоточностью, если к одному соединению подключено несколько потоков.
Таким образом, решение могло открыть отдельное соединение под капотом, но совместно использовать один объект соединения для всего соединения, если не для всей виртуальной машины. JDBC предоставляет только набор результатов, который может быть закрыт, поэтому они могут поместить финализатор, который закрывает соединение, если вы не вызвали close для набора результатов и закрыли его самостоятельно. Проблема в том, что если кто-то читает метаданные одновременно, соединение закрывается из-под него, и, следовательно, происходит сбой.
Учитывая, что эти тестовые прогоны проходили по очень согласованному пути кода, вполне возможно, что шаблон использования памяти был довольно стабильным при запуске, что приводило к тому, что сборка мусора происходила в одно и то же время, но не всегда в одно и то же время. , что соответствует наблюдению, что оно не всегда падало в одном и том же месте.
Это теория. Я не уверен, как это подтвердить, но если проблема не вернется, это мое предположение. Извлеченный урок: всегда закрывайте набор результатов, читая метаданные (и вообще).
РЕДАКТИРОВАТЬ (через долгое время): Хотя в целом вышеупомянутое все еще может быть правдой, в коде произошла другая проблема - он использовал сам финализатор. Таким образом, у вас была обертка вокруг соединения, которое закрывало соединение в финализаторе, но позволяло открывать соединение другим. Еще одно важное правило кодирования: если ваш финализатор закрывает ресурсы, всегда следите за тем, чтобы ничто не могло получить к ним доступ, не имея ссылки на класс, содержащий их.