Consumo de memória diferente com configurações semelhantes

2

Eu tenho duas instâncias diferentes do tomcat 7 em dois servidores diferentes (oracle jdk7) com configuração de hardware quase igual (ambos > 24 GB de RAM). Ambos os servidores tomcat possuem a mesma configuração e os mesmos aplicativos da web são implantados nesses servidores. Os catalina opts são os seguintes:

-XX:PermSize=128m -XX:MaxPermSize=512M -Xmx2048m -XX:+CMSIncrementalMode -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC

Durante a execução de um teste de carga (enfatizando uma API REST com solicitações pesadas paralelamente executadas), um dos servidores lança java.lang.OutOfMemoryError: Java heap space (aqui está o stacktrace: link ), o outro servidor funciona bem. Eu não tenho ideia, porque isso está acontecendo. Alguém já enfrentou um problema semelhante?

    
por liecno 06.11.2012 / 13:07

2 respostas

3

Então, o que está acontecendo é que uma de suas JVMs do Tomcat está tentando exceder o heap de 2048 MB que você alocou para ela.

Parece que você está procurando uma resposta específica, tanto quanto uma lista de verificação de coisas para tentar, então aqui vai:

Ficar sem heap é devido a um vazamento de memória, em que você vaza um pouco com cada solicitação ou, em um cenário de carga, pode ser porque você está apenas jogando mais na JVM do que pode manipular. Você quer identificar qual deles é o problema. Comece analisando como você gera sua carga.

Se o problema ocorrer apenas em um alto nível de solicitações paralelas, mas nunca em um nível inferior, você terá um problema de que o número de solicitações vezes a memória necessária para processar cada solicitação seja muito grande. Você precisa fazer com que cada solicitação use menos memória ou limitar a simultaneidade de alguma forma.

Se o problema ocorrer após um determinado número de solicitações terem sido processadas, independentemente da simultaneidade, você terá um vazamento de memória. Você precisa encontrá-lo e recuperar a memória.

Em qualquer cenário, você será muito auxiliado por ter um bom analisador de memória de heap. Existem bons comerciais como o YourKit Java Profiler, ou gratuitos como o Eclipse Memory Analyzer. Encontre uma ferramenta que funcione para você e aprenda a usá-la para ver o que está ocupando a memória. Observe que você não precisa necessariamente usar a ferramenta para iniciar seu programa - se você estiver executando um teste de carga em um servidor, poderá usar a ferramenta de linha de comando jmap do JDK para capturar um dump de heap em um arquivo, e, em seguida, use sua ferramenta para analisar o arquivo de despejo. A ferramenta mostrará a você quais objetos estão ocupando espaço no seu heap.

    
por 29.11.2012 / 20:55
1

Existe algo diferente entre os dois sistemas, caso contrário o comportamento não seria diferente. Observe que muito tempo gasto no GC por um resultado muito pequeno pode causar o erro também. Correr perto dos limites do heap faz com que o GC tenha esse tipo de problema.

Excessive GC Time and OutOfMemoryError

The concurrent collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small. If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.

    
por 03.12.2012 / 13:14