Title: Removing Unnecessary Synchronization in Java
1Removing Unnecessary Synchronization in Java
Gente
2Sincronização
- Métodos/blocos onde apenas um thread executa por
vez - baseado em monitores
- Garantir execuções seguras
3Motivação
- Sincronizações desnecessárias
- objetos acessÃveis apenas por um thread
- overhead 26-60 do tempo de execução
- remover sincronização
4PossÃveis soluções
- Identificar objetos acessÃveis apenas por um
thread - verificação manual tediosa e erro-prone
- mudanças futuras do programa forçam uma nova
análise - Definir versões não sincronizadas do referido
objeto - duplicação de código
5A solução proposta
- Remover em tempo de compilação a sincronização
quando a otimização for possÃvel - Programa de otimização (compilador)
- identifica situações passÃveis da remoção de
sincronização - rescreve parte do programa removendo as
sincronizações desnecessárias
6Identificando situações de otimização
- Excluir os objetos que não podem ser thread-local
- objetos armazenados na heap
- s-escaping (stack-escaping)
- objetos acessÃveis apenas por variáveis locais na
pilha de apenas um thread - s-local
7s-escaping e s-local algoritmo 1
Heap
A
C
B
A é s-local B é s-escape C é s-escape
Pilha do Thread 1
Pilha do Thread 2
8s-escaping e s-local algoritmo 2
Heap
A
C
B
A é s-local B é s-local C é s-escape
Pilha do Thread 1
Pilha do Thread 2
9Algoritmo 2
- s-escaping
- objetos armazenados na heap ou acessÃveis por
mais de uma pilha (thread) - s-local
- objetos acessÃveis apenas por uma única pilha
(thread) - objetos acessÃveis apenas por objetos s-local do
heap
10Problema
- Identificar objetos acessÃveis apenas por objetos
s-local do heap pode levar a algoritmos complexos - transitividade de acessibilidade
- tipos de dados recursivos
- Simplificação objetos acessÃveis por mais de um
nÃvel de referência de um objeto s-local são
s-escaping
11f-escaping
- Objetos referenciados por atributos de objetos
s-escaping
12A análise
- Estágio 1
- detectar objetos s-escaping
- Estágio 2
- detectar objetos f-escaping
13Restrições da linguagem
- Um subconjunto de comandos/expressões
- x y atribuição a variável
- x.f y atribuição a atributo de objeto
- y x.f acesso a atributo
- C.f y atribuição a atributo de classe
- y C.f acesso a atributo de classe
- x new T criação de objeto
- foo(a1, ..., an) chamada de método
- usados para implementar construções de Java como
exceções, arrays, retorno de métodos
14Retorno de métodos
- o hashtable.put(x, y)
- put(hashtable, x, y, o)
15Detectando objetos s-escaping
- Define conjuntos
- s-escape(x)
- é vazio inicialmente (representa falso) e durante
a análise pode conter o booleano true T,
indicando que a variável é s-escaping - AS(x)
- conjunto das variáveis de um métodos que
referenciam o objeto referenciado por x
16Detectando objetos s-escaping
- Inicia a análise pelo método main e vai
analisando os métodos conforme aparecem as
chamadas aos mesmos - Aplicar as regras para cada tipo de comando
- atribuição
- acesso a atributos
- chamada de métodos
17Detectando objetos s-escaping
- Atribuição
- unir (merge) os Alias Set e a propriedade
s-escape das variáveis - x y
- AS(x) ? AS(y)
- s-escape(x) ? s-escape(y)
AS(x) ?1 AS(y)
Análise flow-insensitive
18Detectando objetos s-escaping
- Acesso a atributos (incluindo estáticos)
- a variável passa a ser s-escaping pois indica que
o heap tem uma referência para a mesma ou que a
mesma tem uma referência para o heap - y x.f ou x.f y
- s-escape(y) ? T
19Detectando objetos s-escaping
- Chamada de métodos
- propaga as restrições impostas aos parâmetros
formais dentro do método para os parâmetros reais
(depois de analisar o método) - foo(a0, ..., an)
- ?i ? 0...n s-escape(ai) ? s-escape(pi)
- ?i tal que connected(pi, returnfoo) AS(ai) ?1
AS(an)
an é o parâmetro real que recebe o retorno do
método se houver retorno
20Detectando objetos f-escaping
- AS(x.f)
- conjunto de variáveis que referenciam o objeto em
x.f - f-escape(x)
- conjunto vazio ou T indicando, quando true, que
o objeto referenciado por x também é referenciado
pelo atributo de um objeto s-escaping
21Detectando objetos f-escaping
- Atribuição
- unir (merge) os Alias Set e a propriedade
f-escape das variáveis e dos seus atributos - x y
- AS(x) ? AS(y)
- f-escape(x) ? f-escape(y)
- se s-escape(x) ? s-escape(y) ?
- ?f ? fields(x, y)
- AS(x.f) ?2 AS(y.f)
AS(x) ?2 AS(y)
22Detectando objetos f-escaping
- Acesso a atributos
- x.f y ou y x.f
- se s-escape(x) ?
- AS(x.f) ?2 AS(y)
- se não
- f-escape(y) ? T
FieldAccess(x.f, y)
O que acontecerá com os Alias Set dos atributos
de x.f e de y quando aplicar ?2 na recursão?
O mesmo código já passou pela fase 1
23Detectando objetos f-escaping
- Acesso a atributos estáticos
- C.f y ou y C.f
- f-escape(y) ? T
24Detectando objetos f-escaping
- Chamada de métodos
- Regra 1 - propagar a propriedade f-escape dos
parâmetros formais e seus atributos para os
parâmetros reais e seus atributos - foo(a0, ..., an)
- ?i ? 0...n f-escape(ai) ? f-escape(pi)
- se s-escape(ai) ?
- ?i fields(pi)
- f-escape(ai.f) ? f-escape(pi.f)
25Detectando objetos f-escaping
- Chamada de métodos
- Regra 2 - propagar as restrições entre parâmetros
retornados e variáveis que recebem o retorno - foo(a0, ..., an)
- ?i tal que connected(pi, returnfoo)
- AS(ai) ?2 AS(an)
26Detectando objetos f-escaping
- Chamada de métodos
- Regra 3 - propagar as restrições entre parâmetros
e atributos de outros parâmetros onde haja
atribuição entre eles (trata-se como acesso a
atributo) - foo(a0, ..., an)
- ?f,pi,pj tal que connected(pi.f, pj)
- FieldAccess (ai.f, aj)
27Detectando objetos f-escaping
- Chamada de métodos
- Regra 4 - propagar propriedades entre atributos
de parâmetros que referenciam um mesmo objeto - foo(a0, ..., an)
- ?f,h,pi,pj tal que connected(pi.f, pj.h)
- se s-escape(ai) ? s-escape(aj) ?
- AS(ai.f) ?2 AS(an.h)
- se não se s-escape(ai) ?
- f-escape(ai.f) ? T
28Exemplo
class Handle private Object ref null
synchronized void attach(Object o)
this.ref o
29class Sample static Handle globalHandle
null static m() Handle h1
createHandle() Handle h2
createHandle() Object o1 new
Object() Object o2 new Object()
h1.attach(o1) h2.attach(o2)
globalHandle h2 static Handle
createHandle() return new Handle()
30Exemplo
- Vamos analisar o método m da classe Sample
31Fase 1 - identificando s-escaping
Alias Sets do método m
Alias Set do método createHandle
Alias Sets do método attach
h1
s
this
h2
return
s
s
o
o2
s
o1
32Fase 2 - identificando f-escaping
s
ref
o1
h1
Alias Sets do método m
s,f
h2
s,f
o2
Alias Set do método createHandle
return
s
ref
Alias Sets do método attach
o
this
33Conclusão
- Otimizar o uso dos objetos que não são f-escape e
que possuem métodos sincronizados - otimizar h1
34Otimização
- Definir uma nova subclasse (clone) da classe do
objeto a ser otimizado sem sincronizar os métodos
como na classe original (Handle) - Substituir no método analisado a instanciação do
objeto referenciado por h1 pela nova classe
(clone) - pode ser necessário duplicar factory methods
35Na classe clone
- Definir um construtor que invoca o construtor da
superclasse (classe a ser otimizada) - Copiar os métodos da superclasse removendo o
qualificador synchronized - Remover qualificadores final
- Alterar os qualificadores private para protected
36A classe clone
class HandleUnsync extends Handle public
HandleUnsync() super()
public void attach(Object o) this.ref
o
37A classe e o método otimizados
class Sample // ... static m()
Handle h1 createHandleClone1()
Handle h2 createHandle() // ...
static Handle createHandleClone1()
return new HandleUnsync() // ...
38Bibliografia
- Removing Unnecessary Synchronization in Java.
Jeff Bogda and Urs Holzle. Departament of
Computer Science. University of California