Seu amigo está certo, o java realmente "esquenta" e o nome disso é JIT e Tiered Compilation. O que ocorre é que o Java realiza varias otimizações no codigo em tempo de execução (ex: alinhamento de método, ele transforma seu getMethod-setMethod em um acesso direto ao atributo da classe). Com o tempo e com o decorrer de várias execuções essas otimizações vão se tornando cada mais "violentas" ao ponto que no ultimo nível restará apenas codigo binario (como c++). O contrário também pode ocorrer, que é o evento de "desotimização", mas o seu impacto é minimo.

A melhor forma de acompanhar esse comportamento de otimizações é utilizar o JMC (Java Mission Control) com o JFR (Java Flight Recorder), dentro da ferramenta há uma aba focada especialmente nisso.

No geral você não precisa se preocupar com o ajuste desses internos da JVM, mas caso queira experimentar, você pode utilizar o paramêtro: -XX:CompileThreshold=NUMERO_DE_EXECUCOES, para controlar o numero de execuções necessárias para a jvm considerar um método apto a ser otimizado.

Outro ponto que pode impactar a velocidade de sua aplicação de forma agressiva é o coletor de lixo e sua versão Java, quanto mais recente for sua versão java, mais performático ele tende a ser.

Por ultimo deixo minha recomendação de paramêtros (que sempre utilizo nos sistemas que trabalho) que você pode testar na sua aplicação:

-XX:MaxRAMPercentage=75 - define o máximo de uso da memoria para 75%, util para ser utilizado em containers. Pq não mais? O container também vai precisar de memoria. Pq não define o minimo como a maioria do pessoal faz? Não é necessário, é um antipattern que pode inclusive prejudicar sua performance. Definir o máximo já é o suficiente, a JVM é inteligente, burro é o dev.

-XX:+UseG1GC - habilita o coletor de lixo G1GC, apesar de não ser recomendado para containers pequenos, ainda sim pode apresentar um desempenho superior em aplicações REST por conta da natureza do seu algoritmo (focado em zonas de objetos jovens).

-XX:MaxGcPauseMillis=100 - quantidade de tempo em milisegundos que você deseja que o coletor de lixo aplique no seu processo.

-XX:PauseTimeIntervalMillis=200 - espaço de tempo entre uma coleta e outra.

links (recomendo ver o link da microsoft):