Basicamente, a estratégia padrão da Oracle para jars ojdbc recentes é "pré-alocar" um array por linha de "pré-busca" que acomoda o maior tamanho possível para retornar dessa consulta. Para todas as linhas. Então, no meu caso, eu tinha alguns VARCHAR2 (4000) lá, e 50 threads (Statements) * 3 colunas de varchar2 * 4000 estavam somando mais de gigabytes de RAM com um setFetchSize de algumas centenas [yikes]. Não parece haver uma opção para dizer "não pré-aloque esse array, apenas use o tamanho conforme eles chegam". Ojdbc ainda mantém esses buffers pré-alocados em torno de entre instruções preparadas (cache/conexão) para que possa reutilizá-los. Definitivamente um porco de memória.
Uma solução alternativa:use
setFetchSize
para alguma quantidade sensata. O padrão é 10, o que pode ser bastante lento em conexões de alta latência. Perfile e use apenas o máximo de setFetchSize que realmente faça melhorias significativas de velocidade. Outra solução é determinar o tamanho real máximo da coluna e substituir a consulta por (assumindo que 50 é o tamanho real máximo conhecido)
select substr(column_name, 0, 50)
Outras coisas que você pode fazer:diminuir o número de linhas de pré-busca, aumentar java
-Xmx
parâmetro, selecione apenas as colunas que você realmente precisa. Depois que conseguimos usar pelo menos a pré-busca 400 [certifique-se de fazer o perfil para ver quais números são bons para você, com alta latência vimos melhorias até o tamanho da pré-busca 3-4K] em todas as consultas, o desempenho melhorou drasticamente.
Suponho que, se você quiser ser realmente agressivo contra linhas "muito longas" esparsas, poderá consultar novamente quando encontrar essas linhas grandes [raras].
Detalhes ad nauseum aqui