O problema pode estar relacionado a este problema da glibc .
Basicamente, quando você tem vários threads alocando memória, a glibc aumentará o número de arenas disponíveis para fazer a alocação de modo a evitar a contenção de bloqueio. Uma arena é de 64 MB. O limite superior é criar 8 vezes o numero de arenas de núcleos. As arenas serão criadas sob demanda quando um thread acessar uma arena que já esteja bloqueada, aumentando assim com o tempo.
Em Java, onde você faz o polimento com threads, isso pode levar rapidamente a muitas arenas sendo criadas. E há alocações espalhadas por todas essas arenas. Inicialmente, cada arena de 64Mb é mapeada apenas para a memória sem uso, mas à medida que você faz as alocações, você começa a usar a memória real para elas.
Seu pmap provavelmente tem listagens semelhantes a esta abaixo. Observe como 324K + 65212K = 65536K, 560K + 64976K == 65536K, 620K + 64916K == 65536K. Ou seja, eles somam 64MB.
00007f4394000000 324K rw--- [ anon ] 00007f4394051000 65212K ----- [ anon ] 00007f4398000000 560K rw--- [ anon ] 00007f439808c000 64976K ----- [ anon ] 00007f439c000000 620K rw--- [ anon ] 00007f439c09b000 64916K ----- [ anon ]
Quanto a soluções alternativas : O bug menciona alguns parâmetros de ambiente que você pode definir para limitar o número de arenas, mas você precisa de uma versão glibc alta o suficiente.