O que o sinalizador UseCompressedOops JVM faz e quando devo usá-lo?

85

O que o sinalizador HotSpot JVM -XX:+UseCompressedOopsfaz e quando devo usá-lo? Que tipo de diferenças de desempenho e uso de memória verei ao usá-lo em uma instância Java de 64 bits (em comparação com não usá-lo)?

Noahlz
fonte
1
Ele compacta ponteiros de 64 bits. Você verá uma redução no inchaço da memória devido ao tamanho aumentado do ponteiro, menos tempo gasto em GC, talvez uma pequena queda no desempenho. jdk1.6.0_22 foi a última Sun JVM a ter esse sinalizador desativado por padrão.
sjr

Respostas:

87

A maioria do HotSpot JVM no ano passado o tinha ativado por padrão. Esta opção permite que as referências sejam de 32 bits em uma JVM de 64 bits e acessem perto de 32 GB de heap. (mais de ponteiros de 32 bits podem) (você também pode ter memória off heap quase ilimitada). Isso pode economizar uma quantidade significativa de memória e melhorar potencialmente o desempenho.

Se você quiser usar esta opção, sugiro que você atualize para uma versão que a tenha ativado por padrão, pois pode haver um bom motivo, como bugs, por que não foi ativado anteriormente. Experimente a atualização 23 do Java 6 ou atualização 5 do Java 7.

Resumindo, não ligue, use uma versão que o tenha ativado por padrão.


Atualizar:

No Java 8, você tem a opção de definir o -XX:ObjectAlignmentInBytes=e, de fato, se o tamanho do heap for 64 GB, ele usará -XX:ObjectAlignmentInBytes=16e ainda usará referências de 32 bits.

Peter Lawrey
fonte
Eu li este artigo: community.oracle.com/message/10019916 que afirma que devemos sempre usar esse sinalizador manualmente, mesmo se estiver habilitado por padrão. Alguma ideia?
vanval
1
@vanval Isso é recomendado se você estiver usando JE cache Isso porque não pode descobrir se você está usando compressas opa ou não por algum motivo. Posso pensar em alguns métodos que podem te dizer isso btw. Você não deve precisar especificá-lo na linha de comando IMHO, a menos que queira que o JVM falhe se não estiver habilitado. por exemplo, você tem um heap de 64 GB em Java 8.
Peter Lawrey
3
Acabei de executar alguns testes no Win8 x64 i7-4702MQ JDK 8 u40 com 7 GB xms e xmx, dos 7 GB, 5,4 GB são usados ​​por uma grande árvore carregada de um banco de dados do Access. Meu ponto é: especificar manualmente o sinalizador -XX: + UseCompressedOops leva a uma diminuição de 20% no desempenho (ao gerar a árvore grande) e mais 1 (de 3 a 4) pausa longa de GC (com GC padrão). Você pode interpretar isso como uma diminuição no desempenho ou como um aumento na pausa do GC. De qualquer forma, foi 20% mais lento.
zmirc
1
Cada aplicativo possui sua própria memória e perfil de uso. No nosso caso, um aplicativo de desktop vindo de 32bits jvm, o sinalizador + UseCompressedOops salvou o dia, pois manteve o uso de memória baixo o suficiente para caber na velha máquina de 4GB do cliente e aumentou o desempenho em 30%, quando comparado com 32bits jvm.
Alex Byrth