Limite de sobrecarga de GC excedido

93

Qual é o tempo de amostragem que a JVM usa para lançar 'java.lang.OutOfMemoryError: limite de sobrecarga de GC excedido'? Eu sei que você pode controlar 98% e 2% com os parâmetros GCTimeLimit e GCHeapFreeLimit, mas qual é o tempo de amostragem?

PRK
fonte

Respostas:

82

De Java SE 6 HotSpot [tm] Ajuste de coleta de lixo de máquina virtual

Os seguintes

Tempo excessivo de GC e OutOfMemoryError

O coletor simultâneo lançará um OutOfMemoryError se muito tempo estiver sendo gasto na coleta de lixo: se mais de 98% do tempo total for gasto na coleta de lixo e menos de 2% do heap for recuperado, um OutOfMemoryError será lançado. Este recurso foi projetado para evitar que os aplicativos sejam executados por um longo período de tempo enquanto fazem pouco ou nenhum progresso porque o heap é muito pequeno. Se necessário, este recurso pode ser desabilitado adicionando a opção -XX: -UseGCOverheadLimit à linha de comando.

A política é a mesma do coletor paralelo, exceto que o tempo gasto na execução de coletas simultâneas não é contado para o limite de tempo de 98%. Em outras palavras, apenas as coletas realizadas enquanto o aplicativo está parado contam para o tempo excessivo de GC. Essas coleções são normalmente devido a uma falha de modo simultâneo ou uma solicitação de coleção explícita (por exemplo, uma chamada para System.gc ()).

em conjunto com uma passagem mais abaixo

Um dos usos mais comuns da coleta de lixo explícita ocorre com a coleta de lixo distribuída (DGC) de RMIs. Os aplicativos que usam RMI referem-se a objetos em outras máquinas virtuais. O lixo não pode ser coletado nesses aplicativos distribuídos sem ocasionalmente coletar o heap local, portanto, o RMI força coletas completas periodicamente. A frequência dessas coleções pode ser controlada com propriedades. Por exemplo,

java -Dsun.rmi.dgc.client.gcInterval=3600000

-Dsun.rmi.dgc.server.gcInterval=3600000 especifica coleta explícita uma vez por hora em vez da taxa padrão de uma vez por minuto. No entanto, isso também pode fazer com que alguns objetos demorem muito mais para serem recuperados. Essas propriedades podem ser definidas até Long.MAX_VALUE para tornar o tempo entre as coleções explícitas efetivamente infinito, se não houver desejo de um limite superior na oportunidade da atividade DGC.

Parece implicar que o período de avaliação para determinar 98% é de um minuto, mas pode ser configurável na JVM da Sun com a definição correta.

Claro, outras interpretações são possíveis.

Edwin Buck
fonte
5
A coleta de lixo distribuída por RMI é uma atividade não relacionada à coleta de lixo regular. Portanto, não vejo como você pode inferir o que acabou de fazer.
Stephen C
2
A inferência não é perfeita ou mesmo correta, é por isso que "parece implicar" é usado em vez de "implica". Se você concordar com a observação de que se o pessoal da Sun usou um minuto para determinar o intervalo de coleta de lixo para RMI, esse tempo de coleta na coleta simultânea só é calculado acumulado quando o programa principal é interrompido e dá um salto de fé , então as chances são boas de que 98% seja coletado em um minuto. É um número mágico, mas um minuto é um número mágico freqüentemente usado em comparação com 3,5 minutos.
Edwin Buck
@StephenC, você quer dizer que mesmo se definirmos, -XX:+DisableExplicitGC isso não afetará a configuração relacionada ao RMI e o sistema invocará gc na frequência definida com o parâmetro-Dsun.rmi.dgc.server.gcInterval
Steephen
1
@Steephen - Não. Não é isso que estou dizendo. Estou falando sobre esta afirmação: "Parece implicar que o período de avaliação para determinar os 98% é de um minuto ..." . E observe que Edwin concorda que a inferência é "imperfeita". A inferência é baseada na suposição de que o pessoal da Sun que implementou o RMI (e DGC) estava em comunicação próxima com o pessoal que implementou o mecanismo de limite de sobrecarga do GC. Suspeito que os dois desenvolvimentos realmente aconteceram em momentos diferentes. Observe que a -Dsun.rmi.dgc.server.gcIntervalpropriedade existe desde Java 1.2.
Stephen C
1
De qualquer forma, uma abordagem melhor para encontrar a resposta real para essa pergunta seria olhar o código-fonte do OpenJDK.
Stephen C