Linux, Open-source, Programação e Produtividade

HashMap consumindo 100% de CPU

Jonas Abreu em 25/03/2012

Uma vez enfrentei um caso estranho. O cluster subia normalmente e as primeiras horas nada de estranho aparecia. Depois de umas 3 ou 4 horas, um dos cores da máquina ficava em 100% e não descia mais. Passadas mais algumas horas, outro core ficava em 100% e também não descia. Isso se repetia até a máquina não ser mais capaz de responder, momento em que o "watch dog" notava que tinha algo muito sério acontecendo, matava a aplicação e reiniciava.

Esse é um problema clássico relacionado à programação concorrente. Em algum momento surgia uma interação estranha que causava um loop infinito.

Depois de rastrear bastante, descobrimos que o culpado era uma cache que utilizava um java.util.HashMap para armazenar os dados.

Em diversos casos isso não seria problemático, mesmo o HashMap não sendo thread-safe. O problema é que essa cache era preenchida de forma lazy e um HashMap.put pode causar problemas em um ambiente concorrente.

Segundo a documentação do HashMap, ele pode ser compartilhado entre diversas threads desde que sejam chamados apenas métodos que não alterem sua estrutura. O put muda sua estrutura. E as vezes pode gerar uma condição de corrida que causa um loop infinito.

Mudar para java.util.concurrent.ConcurrentHashMap resolveu o problema.

Creative Commons License
HashMap consumindo 100% de CPU de Jonas Abreu está licenciado sob Creative Commons License.