Quanto ao htop estar errado, acho que você ativou as informações do thread, assim, cada entrada do java que você vê é um thread do mesmo processo. Para verificar isso, alterne "mostrar segmentos" (pressione "H" para alternar).
A partir da captura de tela htop, percebo que seu servidor tem 8G de RAM, portanto, se você tiver limitado a JVM a 5G + PermGen + alguma sobrecarga, deverá estar ok, supondo que não haja outros processos com fome de memória em execução.
A próxima coisa a verificar é o coletor de lixo, dependendo da sua versão do java, há um sinalizador (pelo menos no oracle java / openjdk) que faz a JVM registrar cada evento do GC, geralmente: -verbose:gc -XX:+PrintGCDateStamps -Xloggc:SOMEFILENAME
e até mesmo aumentando Atividade de GC, em caso de vazamento de memória, você verá a coleta de lixo se tornando mais frequente à medida que o tempo passa, até usar toda a CPU tentando liberar memória sem sucesso, e você pode obter exceções de memória em seus logs.
Nesse ponto, você tem que kill -9
do aplicativo para o seu problema.
Mas agora você terá um log da atividade post-mortem do GC para provar que há vazamentos de memória ou não.
Em seguida, se você tiver mais de um aplicativo implantado, tente dividir os aplicativos em uma única instância do tomcat, se possível. Ou ative o dump de pilha em memória insuficiente.
Assim como o que fazer sem a possibilidade de consertar o código, supondo que haja memória de alho-poró configurando um monitoramento na freqüência de GC, por exemplo, se houver 3 tentativas completas de GC em um minuto, reinicie o tomcat automaticamente.
Feio, mas se não houver outras opções, você pode dormir à noite.