Atualização do Groovy causando uma tonelada de GroovyClassLoaders inoperantes no PermGen

Eu tenho um projeto Java 7 que executa scripts a cada n minutos por n processos. Aqui está um exemplo do código que executa os scripts.

ScheduledFuture scheduledFuture = scheduledService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try (GroovyClassLoader cl = new GroovyClassLoader()) {
                    // Load up reusable script modules in the class loader
                    Class scriptClass = cl.parseClass(scriptSource);
                    Foo script = optimizationClass.newInstance();

                    // Tell Groovy that we don't need class meta info
                    GroovySystem.getMetaClassRegistry().removeMetaClass(scriptClass);
                    script.run();
                    cl.clearCache();
                } catch (IOException e) {
                    LOGGER.error("Failed to cleanup Groovy class loader, this will cause a memory leak", e);
                }
            }
        }, 0, scheduledRun, TimeUnit.SECONDS);

        scheduledFuture.get();

Por alguma razão, com o Groovy 2.1.7, não há vazamento de memória no Perm Gen. Ao atualizar para o Groovy 2.3.8 ou Groovy 2.2.0, o Perm Gen fica cheio de carregadores de classe do Groovy mortos.

0x000000071ada2cd0 33 488160 0x000000071b2493c8 mortos Groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x00000007265883b8 33 488160 0x0000000725837270 mortos Groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x00000007157b5da0 26 370736 0x000000072326f468 org vivo / codehaus / Groovy / runtime / callsite / CallSiteClassLoader @ 0x00000007c831d388 0x000000071ada1fb0 32 423944 0x000000071af03a98 mortos Groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x0000000719d605b0 32 456520 0x000000071af04798 mortos Groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x0000000725b82500 0 0 0x000000072326f468 mortos Groovy / lang / GroovyClassLoader @ 0x00000007c74c33e8 0x00000007263eef80 34 532448 0x0000000726d5c678 mortos Groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x000000072687b3c8 33 485288 0x0000000726c36340 dead groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x0000000725d56db0 33 485288 0x000000072607bcc0 dead groovy / lang / GroovyLoa / Groovy der @ 0x00000007c7b70ef8

Espero até que um GC completo aconteça, mas parece que qualquer versão após o Groovy 2.2 estiver fazendo com que o Perm Gen seja preenchido. Eu verifiquei as notas de versão entre a versão em que estava e a versão atualizada e não notei nenhuma alteração que pudesse desencadear isso.

Eu verifiquei aqui para problemas semelhantes e tentei algumas sugestões, mas sem sorte. Alguma idéia sobre a causa?

Atualizar:
Eu fiz um Diff no GrepCode no GroovyClassLoader de 2.1.7 a 2.2.0 e não houve alterações. Também peguei um arquivo de despejo de pilha quando o aplicativo estava em execução e não havia caminhos para as raízes do GC para obter referências fortes.

A questão parece estar por aqui:

Class scriptClass = cl.parseClass(scriptSource);
Foo script = scriptClass.newInstance();

Quando não compilo o script, obtive 0 Groovy ClassLoaders no Perm Gen. Quando compilo o script, mas não o executo, fico com o Groovy ClassLoaders morto.

Atualizar:
Encontrou o código que está causando o vazamento.

Foo script = scriptClass.newInstance();

Não tenho certeza de como corrigir isso, pois preciso criar uma nova instância para executar o script.

questionAnswers(2)

yourAnswerToTheQuestion