Você está na página 1de 75

Máquinas Virtuais como Apoio à Atividade de

Teste de Software

Vinícius Humberto Serapilha Durelli


SERVIÇO DE PÓS-GRADUAÇÃO DO ICMC-USP

Data de Depósito: 24 de junho de 2010

Assinatura:

Máquinas Virtuais como Apoio à Atividade de Teste de Software

Vinícius Humberto Serapilha Durelli

Orientador: Prof. Dr. Márcio Eduardo Delamaro

Monografia apresentada ao Instituto de Ciências Ma-


temáticas e de Computação — ICMC/USP, para o
Exame de Qualificação, como parte dos requisitos
para obtenção do título de Doutor em Ciências de
Computação e Matemática Computacional.

USP - São Carlos


Junho/2010
Resumo

Desde a introdução da linguagem Java, máquinas virtuais têm se tor-


nado uma tecnologia cada vez mais difundida e consolidada. Essa tecno-
logia proporciona várias vantagens como portabilidade multiplataforma
e gerenciamento de memória automatizado. Todavia, o ambiente de exe-
cução provido por máquinas virtuais não contém funcionalidades que
facilitam e automatizam a condução de atividades de Teste de Software.
Adicionalmente, os resultados do mapeamento sistemático conduzido
com o intuito de obter informações sobre os tipos de funcionalidades que
vêm sendo pesquisadas e implementadas em máquinas virtuais indicam
que poucas pesquisas com o propósito de diminuir o esforço necessário
para aplicação de atividades de Teste de Software vêm sendo realizadas.
Adversamente a essa carência, considera-se que o ambiente de execução
provido por máquinas virtuais é propício para ser adaptado com a fina-
lidade de se inserir tal suporte. Desse modo, no contexto deste projeto
pretende-se estudar quais funcionalidades auxiliariam a condução de
atividades de Teste de Software quando introduzidas às máquinas virtu-
ais existentes. Além disso, propõe-se que as funcionalidades resultantes
sejam adicionadas a uma implementação da máquina virtual Java.

iii
Abstract

Virtual machines executing high level languages have become a trend


since the introduction of the Java language. Virtual machines provide
developers with several advantages such as platform-independence and
automatic memory management. Nevertheless, these execution environ-
ments have no features that automate and facilitate the conduction of
testing activities throughout software development cycle. Moreover, the
systematic mapping that was conducted in order to provide additional
insight into the sorts of features that have been introduced into virtual
machines shows that there is a lack of research dealing with develo-
ping features geared towards lessening the amount of effort required to
perform testing activities in the context of languages based upon vir-
tual machines. The main claim of this doctoral research is that virtual
machines provide a reasonable basis upon which testing features can
be integrated, thereby supplying a platform-independent testing and de-
velopment environment. Therefore, this research project intends to fill
in the current gap by devising testing features that take advantage of
the environment provided by virtual machines and the control they have
over program execution. In addition, it is aimed to implement the resul-
ting features in an extant implementation of the Java virtual machine.

iv
Sumário

1 Introdução 1
1.1 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Organização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Máquinas Virtuais de Linguagem de Programação 4


2.1 Virtualização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Máquinas Virtuais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Máquinas Virtuais de Sistema . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3.1 Vantagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4 Máquinas Virtuais de Processo . . . . . . . . . . . . . . . . . . . . . . . . 11
2.4.1 Máquinas Virtuais de Linguagens de Programação . . . . . . . . . 12
2.4.2 Vantagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.5 Máquina Virtual Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.1 Conjunto de Instruções Virtuais . . . . . . . . . . . . . . . . . . . . 18
2.6 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3 Mapeamento Sistemático 21
3.1 Processo para Condução de Mapeamentos Sistemáticos . . . . . . . . . . 22
3.2 Definição das Questões de Pesquisa . . . . . . . . . . . . . . . . . . . . . 22
3.3 Busca por Estudos Primários . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.4 Screening . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.5 Keywording . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.6 Categorização Resultante . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.6.1 Otimização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.6.2 Gerenciamento de Memória Automatizado . . . . . . . . . . . . . . 29
3.6.3 Depuração . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

v
3.6.4 Tolerância a Vazamentos de Memória . . . . . . . . . . . . . . . . . 31
3.6.5 Novas Construções de Linguagens de Programação . . . . . . . . . 31
3.6.6 Profiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.6.7 Programação Orientada a Aspectos . . . . . . . . . . . . . . . . . . 32
3.6.8 Sistemas Embarcados . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.6.9 Segurança . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.6.10Tempo Real . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.6.11Computação Distribuída . . . . . . . . . . . . . . . . . . . . . . . . 35
3.6.12Tolerância a Falhas . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.6.13Compartilhamento de Recursos entre Máquinas Virtuais . . . . . 36
3.6.14Teste de Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.7 Mapeamento dos Estudos Primários e Análise . . . . . . . . . . . . . . . . 37
3.7.1 Mapa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.8 Categorização e Classificação por meio da Ferramenta PEx . . . . . . . . 43
3.9 Ameaças à Validade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.10 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4 Proposta 47
4.1 Proposta de Projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.2 Ambiente para Teste de Mutação . . . . . . . . . . . . . . . . . . . . . . . 49
4.3 Suporte para Teste de Programas Concorrentes . . . . . . . . . . . . . . . 50
4.4 Implementações Examinadas . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.5 Atividades Realizadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.6 Atividades Planejadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.7 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

vi
Lista de Figuras

2.1 Virtualização. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Níveis de abstração e interfaces de um típico sistema computacional. . . 7
2.3 Visão acerca do que consiste uma máquina conforme as perspectivas de
sistema e de processo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 Monitor de máquina virtual (a) e type 2 hypervisor (b). . . . . . . . . . . . 9
2.5 Modelo de distribuição de programas “convencional” e baseado em má-
quina virtual. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6 Threads e seus respectivos frames associados à invocação de métodos. . 17
2.7 Formatos de instruções. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.8 Disposição da pilha de operandos após a execução das instruções da
Listagem 2.1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.1 Visão geral da abordagem para condução de mapeamentos sistemáticos. 23


3.2 Abordagem usada para criação das categorias. . . . . . . . . . . . . . . . 27
3.3 Projeção das publicações nas 5 categorias com maior número de estudos
primários. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.4 Distribuição dos estudos de acordo com a base de dados e o tipo de
publicação. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.5 Mapa contendo a distribuição dos estudos de acordo com as facetas. . . 42
3.6 Categorização e classificações geradas pela ferramenta PEx. . . . . . . . 44

vii
Lista de Tabelas

3.1 Visão geral dos artigos retornos e selecionados . . . . . . . . . . . . . . . 26


3.2 Categorias e seus respectivos acrônimos. . . . . . . . . . . . . . . . . . . 38
3.3 Quantidade de estudos primários por categoria. . . . . . . . . . . . . . . 39

4.1 Cronograma contendo as atividades a serem conduzidas. . . . . . . . . . 54

viii
Listagens

2.1 Trecho de código que adiciona dois inteiros. . . . . . . . . . . . . . . . . . 19

ix
CAPÍTULO

1
Introdução

Teste de Software é uma atividade de Garantia de Qualidade considerada fundamen-


tal no contexto da Engenharia de Software (Bertolino, 2007). Portanto, o desenvol-
vimento de sistemas requer que atividades de Teste de Software, com o propósito de
aperfeiçoar a qualidade e a confiabilidade desses sistemas, sejam efetuadas (Myers
et al., 2004). Todavia, devido à complexidade crescente dos sistemas e ao número de
tecnologias envolvidas, a condução de atividades de teste não é trivial. Conseqüen-
temente, cinqüenta por cento do tempo dedicado ao desenvolvimento de um sistema
bem como pouco mais de cinqüenta por cento do orçamento voltado ao projeto são
despendidos em atividades de teste e correção de problemas (Naik e Tripathy, 2008).
Parte da complexidade envolvida no desenvolvimento de sistemas vem sendo mi-
tigada por meio da introdução de linguagens de programação pertencentes a níveis
cada vez mais altos de abstração. Além das facilidades providas por tais linguagens
contemporâneas, várias delas são compiladas ou executam diretamente em máquinas
virtuais que provêem diversos benefícios como gerenciamento dinâmico de memória e
de threads, segurança, e compatibilidade multiplataforma.
As primeiras implementações de máquina virtual tinham um único objetivo, pos-
sibilitar que programas fossem facilmente portados para plataformas heterogêneas
(Craig, 2005; Smith e Nair, 2005b). Porém, dada as vantagens do ponto de vista
de Engenharia de Software proporcionadas por essa tecnologia, atualmente ela vem
sendo adaptada e utilizada como ambiente de execução para vários tipos de aplicações
como, por exemplo, de tempo real (Auerbach et al., 2007).
Embora consista de uma tecnologia consolidada, amplamente usada tanto no meio
acadêmico quanto na indústria, implementações de máquina virtual não possuem

1
CAPÍTULO 1. INTRODUÇÃO 2

funcionalidade para automatizar e facilitar a condução de atividades de Teste de Soft-


ware. Em vista disso, para que essas atividades sejam devidamente conduzidas, tec-
nologias adicionais devem ser empregadas. Normalmente, tal carência de funciona-
lidade é suprida por meio do uso de ferramentas. Entretanto, em alguns contextos,
a utilização de ferramentas implica na introdução de características indesejadas. Por
exemplo, ferramentas para determinar a cobertura do código, normalmente, instru-
mentam o código sendo testado aumentando assim o tamanho do código objeto.

1.1 Motivação
A principal motivação para realização do projeto em questão é que as máquinas vir-
tuais contemporâneas apresentam carência de funcionalidade que apoie a condução
de atividades de Teste de Software. Considera-se que o ambiente de execução provido
por tais máquinas virtuais é propício para ser adaptado com o propósito de se inserir
tal funcionalidade. Ademais, acredita-se que a aplicação de determinadas técnicas
de Teste de Software seria facilitada e a quantidade de ferramentas envolvidas seria
reduzida caso as máquinas virtuais provessem esse tipo de suporte.
Outro fator que motiva essa pesquisa é que pouco vem sendo explorado nesse
sentido. A maioria dos trabalhos realizados abrange o desenvolvimento de melhorias
não-funcionais a fim de aprimorar o desempenho desses ambientes de execução ou os
algoritmos do mecanismo de gerenciamento de memória automatizado, por exemplo.
Desse modo, pretende-se estudar quais funcionalidades auxiliariam a condução de
atividades de Teste de Software quando introduzidas às máquinas virtuais existentes.
Visto que máquinas virtuais Java são amplamente difundidas, pretende-se introduzir
as funcionalidades resultantes deste projeto em uma implementação dessa máquina
virtual.

1.2 Objetivos
Este projeto fundamenta-se no fato de máquinas virtuais exercem influência sobre
vários tópicos relacionados à execução dos programas. Entretanto, tal propriedade
não vêm sendo explorada no sentido de prover funcionalidades para facilitar a con-
dução de técnicas de Teste de Software. Desse modo, pretende-se pesquisar quais
funcionalidades poderiam ser introduzidas com esse intuito, determinando assim as
características e elementos estruturais desses ambientes de execução que necessitam
ser extendidos ou adicionados.
Objetiva-se também que as funcionalidades propostas sejam implementadas em
uma máquina virtual Java. Com isso, as contribuições podem ser mais apropriada-
mente avaliadas. A fim de se determinar qual implementação será utilizada, inicial-
CAPÍTULO 1. INTRODUÇÃO 3

mente, foram consideradas todas as implementações de máquina virtual Java presen-


tes no mapeamento sistemático descrito no Capítulo 3. Posteriormente, essa lista foi
refinada por meio da aplicação de alguns critérios apresentados no Capítulo 4. As im-
plementações que satisfazem os critérios estabelecidos são detalhadas no Capítulo 4.

1.3 Organização
Este trabalho, além deste capítulo, está organizado como a seguir. No Capítulo 2,
dada a variedade de máquinas virtuais, a apresentação foi organizada de acordo com
a taxonomia de Smith e Nair (2005a,b), baseada nos dois níveis de abstração em que
as máquinas virtuais atuam: sistema e processo. Assim, em tal capítulo são descri-
tos conceitos e definições tanto de máquinas virtuais em nível de sistema quanto de
processo. No entanto, são enfocadas as máquinas virtuais em nível de processo vol-
tadas para suportar linguagens de programação, visto que elas são a tecnologia alvo
da pesquisa subjacente. No Capítulo 3, é descrito o mapeamento sistemático reali-
zado com o objetivo de se obter informações sobre os tipos de aperfeiçoados que vêm
sendo pesquisados, desenvolvidos e introduzidos em máquinas virtuais de linguagem
de programação. Além disso, apresenta-se o mapa resultante, que fornece uma visão
geral das funcionalidades mais pesquisadas e das implementações empregadas. Por
fim, no Capítulo 4, descreve-se a proposta de pesquisa, resultados esperados, e o cro-
nograma destacando as atividades já realizadas e as planejadas para concretização
do projeto.
CAPÍTULO

2
Máquinas Virtuais de Linguagem de
Programação

Neste capítulo são abordados os conceitos fundamentais, relacionados às máquinas


virtuais, necessários para compreensão do trabalho proposto. O conceito implemen-
tado por máquinas virtuais, os diversos tipos de máquinas virtuais existentes, os
níveis de abstração em que elas atuam e suas respectivas vantagens são introduzi-
dos. Para tal, o capítulo encontra-se organizado como a seguir. Na Seção 2.1 são
descritas algumas restrições existentes nos sistemas computacionais e o conceito im-
plementado em máquinas virtuais que tem o propósito de mitigar tais problemas. Na
Seção 2.2 são apresentadas definições relacionadas às máquinas virtuais. Devido à
diversidade de máquinas virtuais existentes, as seções seguintes organizam a apre-
sentação de acordo com a taxonomia proposta por Smith e Nair (2005a,b), baseada
no nível de abstração em que as máquinas virtuais atuam. Assim, na Seção 2.3 são
apresentadas informações relacionadas às máquinas virtuais em nível de sistema e
na Seção 2.4 às de processo, enfatizando a descrição de um tipo de máquina virtual
de processo voltada para suportar linguagens de programação. No contexto deste pro-
jeto pretende-se considerar uma determinada máquina virtual de linguagem de pro-
gramação, a máquina virtual Java. Desse modo, a Seção 2.5 apresenta os principais
elementos que compõem essa máquina virtual bem como o conjunto de instruções
empregado. Por fim, as considerações finais são apresentadas na Seção 2.6.

4
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 5

2.1 Virtualização
Sistemas computacionais são complexos e, normalmente, consistem de vários dispo-
sitivos de hardware e sistemas de software. Adicionalmente, tais sistemas de software
são compostos de vários subsistemas que envolvem diversos tipos de elementos e es-
truturas que colaboram a fim de implementar a funcionalidade proposta. Essa com-
plexidade é abordada, considerando tanto dispositivos de hardware quanto sistemas
de software, utilizando níveis de abstração cujas colaborações são estabelecidas por
meio de interfaces bem definidas (Rosenblum, 2004; Smith e Nair, 2005b).
Por meio da separação em níveis de abstração, detalhes relacionados aos níveis
inferiores podem ser ignorados ou vistos de maneira simplificada pelos superiores,
facilitando assim o desenvolvimento desses níveis (Colburn e Shute, 2007). Usu-
almente, os níveis inferiores são implementados em hardware e os superiores em
software. A comunicação entre esses níveis é realizada por meio de interfaces pre-
viamente definidas, possibilitando que diferentes equipes, desenvolvendo para níveis
distintos, trabalhem de maneira concomitante. Alguns exemplos de interfaces pre-
sentes em sistemas computacionais são: o conjunto de instruções utilizado por uma
plataforma (instruction set architecture, ISA) e a interface de programação de aplicati-
vos (application programming interface, API) de determinado sistema operacional (SO).
Porém, a principal desvantagem de se empregar determinada interface é: componen-
tes e subsistemas desenvolvidos de acordo com a especificação de certa interface não
são compatíveis com outros orientados para interfaces distintas.
Existem processadores voltados para diferentes conjuntos de instruções, bem como
vários SOs como, por exemplo, Windows, Linux e Mac OS X. Todavia, normalmente,
essa heterogeneidade resulta em redução na interoperabilidade, devido às diferenças
entre as interfaces utilizadas. Por exemplo, aplicações, quando distribuídas como
arquivos binários, são compatíveis somente com uma plataforma que possui: (i) o
conjunto de instruções e (ii) o SO empregado durante o desenvolvimento dessas apli-
cações. Outro exemplo são os SOs, que dependem de elementos pertencentes à arqui-
tetura de hardware para qual eles foram desenvolvidos como, por exemplo, existência
de somente um processador (uniprocessor architecture) ou de memória compartilhada
e vários processadores (shared-memory multiprocessor architecture).
Virtualização (virtualization) é uma abordagem que pode ser utilizada para miti-
gar as restrições resultantes da utilização de interfaces heterogêneas. A virtualização
de um sistema computacional ou de software, subsistema, processador, dispositivo
de entrada e saída, etc., faz com que a interface desse elemento e todos os recur-
sos acessíveis a partir de tal interface sejam mapeados para a interface e recursos
do sistema real, ou seja, o sistema que realmente implementa o comportamento em
questão. Desse modo, o sistema real é transformado de forma que ele aparenta ser
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 6

um outro ou até mesmo vários outros sistemas. Virtualização envolve a criação de um


isomorfismo com o propósito de mapear o sistema sendo virtualizado, nesse contexto
denominado guest, no sistema real, designado host (Popek e Goldberg, 1974). Mais es-
pecificamente, conforme ilustrado na Figura 2.1, isomorfismo consiste em mapear os
possíveis estados do sistema guest no host e, para cada operação que altera o estado
do sistema guest, deve haver uma operação correspondente que efetua uma modifi-
cação semelhante no estado do sistema host. Embora tal descrição de isomorfismo
também possa ser utilizada para caracterizar tanto abstração quanto virtualização, de
acordo com Smith e Nair (2005a), os dois conceitos são distintos, pois, virtualização
não necessariamente oculta detalhes de implementação ou de outra natureza.

Figura 2.1: Virtualização; adaptada de Smith e Nair (2005b).

2.2 Máquinas Virtuais


Implementações do conceito de virtualização são denominadas máquinas virtuais (vir-
tual machines, VM). De acordo com Popek e Goldberg (1974), uma máquina virtual
é uma réplica isolada de uma máquina real. Essa definição é mais apropriada para
as primeiras máquinas virtuais. Atualmente, as máquinas virtuais são utilizadas em
diversos níveis de um sistema computacional e, nesses contextos, podem também
implementar máquinas abstratas.
A fim de descrever os vários tipos de máquinas virtuais, é necessário definir as
interfaces em que elas atuam. Na Figura 2.2 são ilustrados os níveis de abstração
e interfaces de um típico sistema computacional. Conforme pode ser observado, há
interfaces que definem a interação entre dois sistemas de software (interface 1), assim
como interfaces envolvendo o hardware subjacente e os demais níveis de software
(interface 4). Três dessas interfaces são especialmente importantes para construção
de máquinas virtuais:

Conjunto de instruções (ISA): estabelece a comunicação entre o primeiro nível de


CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 7

software e o hardware subjacente; é composto pelas interfaces 3 e 4 da Fi-


gura 2.2. O subconjunto de instruções utilizado pelas aplicações é denominado
user ISA. O conjunto responsável pelo gerenciamento e interação com os dis-
positivos de hardware é denominado system ISA, tal conjunto abrange o user
ISA.

Application binary interface (ABI): possibilita que as aplicações acessem diretamen-


te dispositivos de hardware por meio da user ISA (interface 4) ou indiretamente
utilizando invocações de funções do SO (interface 2).

Interface de programação de aplicativos: possibilita acesso aos dispositivos de hard-


ware por meio da user ISA (interface 4) e chamadas de funções pertencentes às
bibliotecas relacionadas (interface 1).

Figura 2.2: Níveis de abstração e interfaces de um típico sistema computacional;


adaptada de Smith e Nair (2005b).

Em cada um dos níveis e interfaces apresentados na Figura 2.2 a visão acerca do


que consiste uma máquina varia conforme a perspectiva. Por exemplo, considerando
a perspectiva de um SO, a máquina com a qual ele interage é implementada pelo
hardware subjacente. A máquina, nesse caso, refere-se a um ambiente de execução
capaz de suportar vários processos que podem pertencer a diferentes usuários. To-
dos esses processos compartilham um sistema de arquivos e dispositivos de entrada
e saída, entre outros recursos. Assim, essa máquina deve, apropriadamente, locar os
recursos disponíveis para todos esses processos e possibilitar que os mesmos intera-
jam entre si por meio desses recursos. Na Figura 2.3(a) ilustra-se essa perspectiva de
sistema cuja máquina é implementada pelo hardware e a interface com o restante do
sistema computacional é o conjunto de instruções.
Considerando a perspectiva de um processo executando determinado programa,
a máquina consiste de um espaço de endereço de memória lógico, bem como regis-
tradores e instruções que possibilitam a execução do código relacionado ao processo.
Outros recursos como, por exemplo, dispositivos de entrada e saída, são acessíveis
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 8

somente por meio de invocações ao SO; usualmente, realizadas por bibliotecas que
executam como parte do processo. Desse modo, a máquina, considerando essa pers-
pectiva de processo, é o formada por uma combinação do SO e do hardware em
questão. Nesse contexto, a interface dessa máquina com o restante do sistema com-
putacional é a ABI, Figura 2.3(b).
Devido a essa ampla abrangência, máquinas virtuais são desenvolvidas por diver-
sos grupos com interesses distintos: desenvolvedores de SOs, linguagens de progra-
mação, compiladores e dispositivos de hardware. Dessa forma, a fim de organizar
a apresentação dos conceitos e detalhes de implementação relacionados aos diver-
sos tipos de máquinas virtuais, as seções seguintes são organizadas de acordo com
uma taxonomia, proposta por Smith e Nair (2005a), fundamentada em dois tipos de
máquinas virtuais: de sistema e de processo.

(a) (b)

Figura 2.3: Visão acerca do que consiste uma máquina conforme as perspectivas de
sistema (a) e de processo (b); adaptada de Smith e Nair (2005a).

2.3 Máquinas Virtuais de Sistema


Máquinas virtuais que proporcionam ambientes de execução para sistemas comple-
tos, ou seja, um SO e seus vários processos relacionados, são denominadas máqui-
nas virtuais de sistema (system virtual machines) (Smith e Nair, 2005a,b). Tal tipo
de máquina virtual atua no nível de abstração apresentado na Figura 2.3(a). Essas
máquinas virtuais foram propostas na década de 60 a fim de possibilitar que os cus-
tosos e escassos recursos de hardware da época fossem compartilhados entre vários
usuários (time sharing) (Holmes, 2005). Uma das primeiras implementações dessa
tecnologia é a IBM’s Virtual Machine Facility/370 (VM/370) (Seawright e MacKinnon,
1979; Tanenbaum, 2007).
Implementações de máquinas virtuais de sistema suportam ambientes de execu-
ção que compartilham os recursos de hardware existentes. Cada um desses ambien-
tes de execução, nesse contexto, é denominado máquina virtual. SOs executam nes-
sas máquinas de maneira isolada, como se os recursos alocados para seus respectivos
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 9

processos fossem reais e gerenciados unicamente pelo SO em questão. Entretanto, o


acesso aos recursos é controlado por outra camada de software que introduz uma in-
terface análoga à provida pelo hardware (Rosenblum e Garfinkel, 2005). Essa camada
de software é denominada monitor de máquina virtual (virtual machine monitor). Ou-
tros nomes para tal camada são: hardware-level virtual machine monitor (Rosenblum,
2004), type 1 hypervisor (Tanenbaum, 2007) e non-hosted hypervisor (Carbone et al.,
2008).
Caso os recursos requisitados pelas máquinas virtuais tenham correspondentes
reais, o monitor de máquina virtual decide como e quando os recursos devem ser
alocados. Caso contrário, a existência de tal recurso deve ser emulada. Além disso,
apesar de cada uma das máquinas virtuais executar um SO (não necessariamente
o mesmo), somente o monitor de máquina virtual executa em modo kernel, assim,
esses SOs são denominados SOs guest (guest operating systems). Uma visão geral da
organização desse tipo de máquinas virtuais de sistema é ilustrada na Figura 2.4(a).
Outro tipo de máquina virtual de sistema é denominado type 2 hypervisor (Tanen-
baum, 2007). Diferentemente de máquinas virtuais type 1 hypervisor que atuam inte-
ragindo diretamente com o hardware, máquinas virtuais type 2 hypervisor comunicam-
se com o SO da plataforma em questão, nesse contexto denominado SO host. O SO
instalado no ambiente de execução proporcionado pela máquina virtual, por sua vez,
é denominado SO guest. Esse tipo de máquina virtual é vista como uma aplicação
comum por parte do SO host, de forma que esse tipo de máquina virtual é também
conhecido como hosted virtual machine (Smith e Nair, 2005a). Conforme pode ser
observado na Figura 2.4(b), essas máquinas virtuais atuam em um nível de abstra-
ção acima em relação às type 1 hypervisor. Exemplos de type 2 hypervisors bastante
difundidos são a VMware Server (Rosenblum e Garfinkel, 2005; VMware Inc., 2010) e
a Xen (Citrix Systems Inc., 2010).
Na seção seguinte são descritas algumas vantagens dessas máquinas virtuais de
sistema.

(a) (b)

Figura 2.4: Monitor de máquina virtual (a) e type 2 hypervisor (b).


CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 10

2.3.1 Vantagens
A utilização de máquinas virtuais de sistema apresenta várias vantagens. Algumas
dessas vantagens são descritas a seguir:

Ambientes isolados: cada máquina virtual tem um ambiente isolado das outras má-
quinas virtuais ou reais. Dessa forma, problemas causados por falhas não afe-
tam o restante do sistema computacional. Adicionalmente, essa autonomia en-
tre máquinas virtuais possibilita isolamento de desempenho, pois, o monitor de
máquina virtual assegura que os recursos requisitados por uma máquina virtual
não afetem adversamente as outras (Rosenblum e Garfinkel, 2005).

Instrumentação de SOs: conforme descrito anteriormente, quando SOs são execu-


tados em máquinas virtuais, todos os acessos aos dispositivos de hardware são
gerenciados pelo monitor de máquina virtual. Assim, as requisições a um de-
terminado tipo de recurso como, por exemplo, dispositivos de entrada e saída,
e informações sobre a máquina virtual responsável pela requisição podem ser
registradas. Para tal, somente o monitor de máquina virtual precisa ser instru-
mentado. Devido a essa característica, vários experimentos avaliando SOs são
conduzidos utilizando máquinas virtuais (Keefe, 1968; Sieh e Buchacker, 2002).

Teste, desenvolvimento e migração de aplicações: máquinas virtuais possibilitam


a utilização de vários SOs, apoiando assim o desenvolvimento e teste de aplica-
ções que necessitam ser portadas para várias plataformas. Semelhantemente,
essa característica torna possível que administradores de sistemas possam man-
ter versões anteriores, a versão atualmente em uso e, possivelmente, novas ver-
sões de determinado SO a fim de lidar com questões de compatibilidade entre
versões. Em ambos os casos mencionados, a solução proposta pela utilização de
máquinas virtuais é mais conveniente que configurar e empregar vários compu-
tadores.

Migração e controle de máquinas virtuais: monitores de máquinas virtuais encap-


sulam os estados das máquinas virtuais sendo gerenciadas, dessa forma, as
máquinas virtuais podem ter sua execução interrompida, concluída (no caso
de execuções previamente interrompidas) ou migrada para outras plataformas.
Além disso, o estado de determinada máquina virtual pode ser configurado para
um estado anterior com o propósito de recuperá-la de uma falha (Rosenblum e
Garfinkel, 2005).

Treinamento: normalmente, durante o aprendizado de um novo SO, usuários ne-


cessitam avaliar o resultado de uma série de comandos que podem corromper a
integridade do SO em questão. Tal treinamento pode ser conduzido utilizando
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 11

um SO instalado em uma máquina virtual, de forma que os outros usuários não


sejam afetados por possíveis problemas.

2.4 Máquinas Virtuais de Processo


Máquinas virtuais de processo fornecem uma versão virtualizada da ABI ou da API
do sistema em questão, atuando no nível de abstração ilustrado na Figura 2.3(b).
Ao contrário das máquinas virtuais de sistema, elas proporcionam um ambiente de
execução para somente um processo. Com a finalidade de implementar esse suporte
ao processo em questão, máquinas virtuais de processo interagem com o SO e com o
hardware.
Conforme mencionado anteriormente, aplicações quando distribuídas como ar-
quivos binários apresentam algumas restrições de compatibilidade; por exemplo, são
compatíveis somente com o conjunto de instruções para o qual elas foram previa-
mente compiladas. Algumas máquinas virtuais de processo têm o propósito de mitigar
essas restrições por meio da emulação de um conjunto de instruções em um hardware
voltado para um conjunto distinto. Esse tipo de implementação de máquina virtual é
denominado emulador (emulator).
Inicialmente, emuladores e máquinas virtuais eram considerados implementações
distintas. A primeira formalização do conceito, proposta por Goldberg (1973), não
abrange tecnologias mais recentes de virtualização como emulação, por exemplo. No
entanto, de acordo com Mallach (1973), a distinção entre essas duas tecnologias é
puramente semântica e histórica, pois, um emulador pode ser definido como uma
máquina virtual cujo conjunto de instruções sendo virtualizado é diferente do empre-
gado pela máquina virtual. Gallard et al. (2009) propõem extensões à formalização
de Goldberg (1973), compreendendo assim as várias tecnologias de virtualização; en-
tre elas emulação. Conseqüentemente, trabalhos mais atuais como, por exemplo, o
de Smith e Nair (2005b), não diferenciam as duas tecnologias.
A maneira mais trivial de emulação é interpretação, que envolve um ciclo de re-
cuperação, decodificação e emulação para cada uma das instruções (fetch-decode-
execute loop). Porém, devido à questões de desempenho, há emuladores que utilizam
tradução binária dinâmica (dynamic binary translation). Basicamente, ao invés de
considerar somente uma instrução de cada vez como ocorre na interpretação, tra-
dução binária dinâmica consiste em traduzir blocos de código binário (binary source
code) para código da plataforma alvo (binary target code). Esses trechos de código
traduzidos são armazenados em cache e devidamente utilizados quando necessário.
Dado que tradução binária é uma das funcionalidades mais importantes desse tipo de
máquina virtual de processo, usualmente, elas são denominadas tradutores binários
dinâmicos (dynamic binary translators) (Smith e Nair, 2005b).
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 12

Uma técnica semelhante à tradução de blocos de código é utilizada quando o con-


junto de instruções empregado pelo sistema guest é o mesmo do host. Porém, ao
invés de “traduções”, os blocos de código são considerados a fim de se introduzir oti-
mizações. Máquinas virtuais que utilizam esse tipo de otimização são denominadas
otimizadores binários (same-ISA binary optimizers).
Máquinas virtuais de processo também são usadas em conjunto com linguagens
de programação a fim de se obter, entre outras funcionalidades, portabilidade multi-
plataforma. Nesse contexto, máquinas virtuais implementam uma máquina abstrata,
pois, o ambiente de execução implementado não corresponde diretamente a nenhuma
plataforma real, sendo projetado de acordo com as necessidades da linguagem ou lin-
guagens suportadas. Esse trabalho enfoca a utilização desse tipo de máquina virtual,
assim nas seções seguintes são apresentadas informações relacionadas a essas má-
quinas voltadas ao suporte de linguagens de programação.

2.4.1 Máquinas Virtuais de Linguagens de Programação


Máquinas virtuais têm sido utilizadas como um mecanismo para implementação de
linguagens de programação desde meados dos anos 70 (Craig, 2005; Gough, 2005).
Proporcionar suporte para específicas linguagens de programação é o principal obje-
tivo dessas máquinas virtuais, portanto, elas são referidas como máquinas virtuais de
linguagens de programação (high-level language virtual machines, HLL VMs) (Smith e
Nair, 2005b).
A fim de se definir esse tipo de máquina virtual, bem como os outros elementos
diretamente relacionados, é necessário descrever os níveis de abstração empregados
para representação de programas. De acordo com Rau (1978), existem três categorias
de representação, apresentadas a seguir do nível mais alto de abstração para o mais
baixo:

representação de alto nível (high level representation, HLR): programas implemen-


tados em linguagens como, por exemplo, Java e C++.

representação diretamente interpretável (directly interpretable representation,


DIR): uma representação intermediária restrita a um conjunto reduzido de ope-
radores e sintaxe simples como, por exemplo, Java bytecodes (Gosling, 1993). É
importante ressaltar que os conjuntos de instruções utilizados nessas represen-
tações intermediárias não são voltados para uma plataforma real1 .

representação diretamente executável (directly executable representation, DER):


arquivos binários no conjunto de instruções de uma determinada plataforma.
1
Embora a Sun Microsystems e a ARM tenham desenvolvido processadores voltados para bytecodes.
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 13

Há, essencialmente, duas formas de se implementar linguagens de programação:


por meio de compilação ou interpretação (Craig, 2005). Compiladores são, normal-
mente, específicos de plataforma, gerando código voltado unicamente para a plata-
forma para a qual eles foram concebidos, ou seja, uma representação diretamente
executável2 . Interpretadores atuam sobre representações de alto nível ou diretamente
interpretáveis.
A utilização de máquinas virtuais de linguagens de programação possibilita que
as duas abordagens, compilação e interpretação, sejam usadas. As duas abordagens
podem ser combinadas em um ambiente de execução que implementa uma máquina
abstrata voltada para suportar uma determinada linguagem de programação. Para
prover tal suporte, elas empregam estruturas internas de armazenamento e, em al-
guns casos, um conjunto de instruções próprio. Esse conjunto de instruções, por sua
vez, é projetado de acordo tanto com características arquiteturais da máquina virtual
quando da linguagem de programação subjacente. Adicionalmente, no contexto de
máquinas virtuais de linguagens de programação, essa representação diretamente in-
terpretável é normalmente referida como conjunto de instruções virtuais (virtual ISAs,
V-ISAs) (Smith e Nair, 2005a,b). Desse modo, máquinas virtuais de linguagem de pro-
gramação consistem de (i) um ambiente de execução que implementa uma máquina
abstrata e que (ii) utiliza um conjunto de instruções que reflete as características da
linguagem de programação bem como as da máquina virtual.
Considerando linguagens compiladas, os passos convencionais envolvidos para
execução de um determinado programa são ilustrados na Figura 2.5(a). Inicialmente,
o frontend do compilador produz uma representação intermediária com base no có-
digo fonte do programa. Posteriormente, o backend gera o código objeto a partir
da representação intermediária produzida anteriormente. Por fim, o carregador (lin-
ker/loader) realiza as adaptações necessárias para que o código objeto seja carre-
gado na memória, possibilitando a execução desse código por parte da plataforma
em questão (Aho et al., 2007). Programas desenvolvidos em linguagens compiladas
são, geralmente, distribuídos como código objeto. No entanto, uma limitação desse
formato de distribuição (por ele ser semelhante ao código binário, com exceção de
algumas referências simbólicas abordadas pelo carregador) é que ele é específico de
plataforma.
As primeiras máquinas virtuais surgiram com o propósito de abordar essa limita-
ção de compatibilidade, de modo que as linguagens baseadas em máquina virtuais
utilizam um esquema conforme o demonstrado na Figura 2.5(b). Nesse esquema o
compilador produz, utilizando o conjunto de instruções virtuais, uma representação
2
O compilador GNU é um contra-exemplo parcial, pois sua versão completa possui geradores de
código para mais de uma plataforma. Outra exceção são compiladores Java, que produzem código
numa representação diretamente interpretável.
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 14

intermediária semanticamente equivalente ao código fonte do programa. Antes da


execução, uma entidade (verifier/loader) é responsável por carregar a representa-
ção diretamente interpretável previamente criada pelo compilador e, em alguns ca-
sos, efetuar algumas verificações e convertê-la para sua respectiva representação in-
terna. Durante a execução, a máquina virtual executa essa representação interna,
transformando-a nas operações da plataforma subjacente.
Normalmente, programas desenvolvidos utilizando linguagens baseadas em má-
quina virtuais são distribuídos na representação diretamente interpretável, ou seja,
usando o conjunto de instruções virtuais da máquina. Desse modo, tais programas
podem ser executados em qualquer plataforma que possua uma implementação da
máquina virtual subjacente.

(a) (b)

Figura 2.5: Modelo de distribuição de programas: no modelo “convencional”, ilustrado


em (a), código dependente de plataforma é distribuído; considerando linguagens ba-
seadas em máquinas virtuais, os programas são distribuídos em código intermediário
interpretável e independente de plataforma e são executados pela máquina virtual
subjacente, conforme ilustrado em (b).

Uma das primeiras máquinas virtuais que apresentou o esquema da Figura 2.5(b)
foi implementada para fornecer suporte para a linguagem Pascal, a saber: P-machine
(também conhecida como P-code machine), cujo conjunto de instruções virtuais é
denominado P-code (Nelson, 1979) e o compilador P-compiler; todos esses elemen-
tos eram coletivamente referidos como P-system (Wirth, 1993). A P-machine possui
tanto arquitetura quanto conjunto de instruções baseados em pilha. Posteriormente,
uma máquina virtual também baseada em pilha foi proposta para linguagem de pro-
gramação Smalltalk. Deutsch e Schiffman (1984) descrevem a máquina virtual para
Smalltalk, denominada ParcPlace, como a primeira máquina virtual moderna dado
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 15

que ela introduziu implementações para várias técnicas amplamente utilizadas atu-
almente: compilador just-in-time (JIT) e cache de código nativo (native code cache),
ambos empregados a fim de aprimorar o desempenho.
Apesar da ampla adoção dessas máquinas virtuais como ambientes de execução
para linguagens de programação, o responsável pela popularização de tal tecnolo-
gia foi o advento da plataforma Java, durante a segunda metade dos anos 90. As
principais diferenças entre a máquina virtual Java (Java virtual machine, JVM) e as
máquinas mencionadas anteriormente são o suporte para redes de computadores he-
terogêneos e a introdução de mecanismos para garantir a integridade da máquina vir-
tual nesse ambiente distribuído. Atualmente, várias linguagens de programação têm
seus ambientes de execução baseados em máquinas virtuais com arquiteturas base-
adas em pilha como, por exemplo, Python (Lutz, 2009), Ruby (Flanagan e Matsumoto,
2008), Groovy (Koenig et al., 2007), Prolog (Clocksin e Mellish, 2003) e Scheme (Dyb-
vig, 2009), ou baseadas em registradores (register-transfer model) como Perl 6 (Randal
et al., 2004) e Lua (Ierusalimschy, 2006).

2.4.2 Vantagens
A utilização de máquinas virtuais como ambiente de execução para linguagens de
programação proporciona diversas vantagens:

Gerenciamento de memória automatizado: o gerenciamento de memória manual,


ou seja, realizado explicitamente pelo programador, é complexo e pode resultar
na ocorrência de vários problemas: (i) ponteiros para objetos que já foram desa-
locados (dangling pointers); (ii) o mesmo espaço na memória pode ser desalocado
duas vezes (double-free); e (iii) vazamentos de memória (memory leaks) (Smith
e Nair, 2005a). Um dos benefícios proporcionados pelo ambiente de execução
implementado por máquinas virtuais é o gerenciamento automático de memória
por meio de garbage collectors (Jones e Lins, 1996). De modo que, durante o de-
senvolvimento, os programadores não necessitam abordar alguns tópicos relaci-
onados ao gerenciamento de memória. Por exemplo, por meio desse mecanismo,
na maioria das vezes, o programador não precisa desalocar explicitamente me-
mória.

Compatibilidade multiplataforma: foi a motivação inicial para a criação das pri-


meiras máquinas virtuais de linguagem. Conforme mencionado, o conjunto de
instruções virtuais é uma representação não associada a nenhuma plataforma
(platform neutral). Assim, a distribuição de programas desenvolvidos em lingua-
gens que são compiladas para essas representações é facilitada, pois, o único
pré-requisito é a existência de uma implementação da máquina virtual corres-
pondente a esse conjunto de instruções virtuais.
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 16

Segurança: dado que as máquinas virtuais modernas possibilitam que programas


sejam obtidos a partir da Internet, que não envolve somente fontes fidedignas,
esse tipo de máquina virtual emprega mecanismos de verificação para avaliar a
integridade desses programas. Tais mecanismos, usualmente, atuam sobre o
conjunto de instruções virtuais.

2.5 Máquina Virtual Java


Devido à ampla adoção da linguagem Java, uma implementação da máquina virtual
dessa linguagem será empregada para a condução deste projeto de pesquisa. Desse
modo, nesta seção apresenta-se uma visão geral dos principais elementos estruturais
que compõem e definem o comportamento de máquinas virtuais Java de acordo com
o documentado na especificação desse ambiente de execução.
A máquina virtual Java é uma máquina computacional abstrata que possui seu
próprio conjunto de instruções e gerencia várias estruturas de dados durante exe-
cução (Li, 1998; Lindholm e Yellin, 1999). Algumas dessas estruturas são criadas
quando a máquina virtual é iniciada (on start-up) e eliminadas somente ao final da
execução. Outras são associadas às threads (per-thread runtime data areas), sendo
criadas conforme cada nova thread é invocada e eliminadas quando a thread em
questão termina. Por exemplo, cada thread criada é associada a uma pilha (Java
virtual machine stack). Essa pilha é dividida em frames (framed stack) que são aloca-
dos conforme métodos são invocados e desalocados assim que o método responsável
pela alocação do frame retorna. Tais frames, ilustrados na Figura 2.6, contêm áreas
para o armazenamento de variáveis locais e realização de computação, consistindo
dos seguintes elementos:

• uma pilha last-in-first-out (LIFO) local, denominada pilha de operandos (operand


stack), usada no armazenamento de parâmetros para invocação de outros méto-
dos, recepção de resultados dos métodos invocados a partir do frame em questão
e, principalmente, para conter resultados temporários envolvidos na realização
de computações;

• um conjunto de variáveis locais (local variable array) usado para armazenar os


parâmetros do método associado ao frame, variáveis locais e, caso o método
associado seja de instância, a pseudo variável this que indica o objeto sob o
qual o método está executando (Craig, 2005);

• uma referência ao código sendo executado pela thread, mais especificamente,


uma referência para o runtime constant pool da classe que define o método sendo
executado;
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 17

• um registrador de PC (PC register), que indica a instrução atual sendo executada


pela thread.

O armazenamento global é organizado em duas estruturas que são compartilha-


das entre todas as threads, uma voltada para o armazenamento de código e meta-
informações sobre classes e interfaces e outra para manter objetos e arrays. A es-
trutura que contém código e meta-informações, criada durante a inicialização da má-
quina virtual, é denominada área de métodos (method area) (Lindholm e Yellin, 1999).
No contexto dessa estrutura, cada classe ou interface é associada a um runtime cons-
tant pool que é análogo a uma tabela de símbolos (symbol table) de linguagens con-
vencionais (Craig, 2005). Runtime constant pools armazenam desde constantes nu-
méricas a código relacionado aos métodos e construtores. A área de dados, também
criada durante a inicialização da máquina virtual, a partir da qual todos objetos e
arrays, assim como algumas outras estruturas como a área de métodos, são alocados
é denominada heap. Dado que o espaço de armazenamento dedicado a essa estrutura
é limitado, quando determinados objetos não podem mais ser referenciados, a memó-
ria alocada deve ser liberada. Para tal, o mecanismo de gerenciamento automático
de memória atua nesse espaço de armazenamento alocado para a heap, liberando
espaço por meio da eliminação de objetos e frames de métodos que podem ser desa-
locados; uma visão geral desse mecanismo e os algoritmos usados são descritos na
Subseção 3.6.2.

Figura 2.6: Threads e seus respectivos frames associados à invocação de métodos.


CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 18

Conforme exposto anteriormente, o conjunto de instruções virtuais reflete impor-


tantes características tanto da linguagem de programação quanto da máquina virtual.
Portanto, com o intuito de fornecer informações adicionais sobre a máquina virtual
Java, a seção seguinte contém uma descrição do conjunto de instruções virtuais uti-
lizado.

2.5.1 Conjunto de Instruções Virtuais


Máquinas virtuais Java são voltadas para um formato binário particular. Arquivos
nesse formato possuem a extensão .class e são compostos por instruções denomi-
nadas bytecodes (Gosling, 1993). Um bytecode consiste de um código indicando a
operação que deve ser realizada (opcode byte) e zero ou mais operandos. Os formatos
de instruções possíveis são detalhados na Figura 2.7. Várias instruções consistem
de somente um byte, ou seja, somente o opcode, Figuras 2.7(a). Outras instruções
são formadas pelo opcode e um ou dois bytes que são usados como índices para
runtime constant pools ou para os conjuntos de variáveis locais dos frames, Figu-
ras 2.7(b) e (c). Há instruções que, além do opcode, contêm um ou dois bytes de
dados, conforme ilustrados nas Figuras 2.7(d) e (e); tais dados podem ser constantes
ou endereços (offsets) para outras instruções.

(a)

(b) (c)

(d) (e)

Figura 2.7: Formatos de instruções.

A maioria das instruções pertence a um dos seguintes grupos: instruções de (i)


fluxo de controle, (ii) manipulação de dados ou da (iii) pilha. As instruções de fluxo de
controle são usadas para realização de transferência de controle. Operações aritmé-
ticas, lógicas e sobre bits são abordadas pelas instruções de manipulação de dados;
normalmente, essas instruções contêm somente um byte pois os operandos são ex-
traídos da pilha e os resultados armazenados na pilha. As instruções que manipulam
a pilha envolvem o acesso e armazenamento tanto no conjunto de variáveis locais
quanto na pilha de operandos (Craig, 2005). O conjunto também abrange instruções
voltadas para suportar construções de linguagens orientadas a objetos. Tais instru-
ções realizam operações como: criação de objetos, invocação de métodos e acesso e
atualização de variáveis de classe e de instância. Adicionalmente, instruções para
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 19

suportar o mecanismo de tratamento de exceções da linguagem (Gosling et al., 2005),


threads e monitores também são definidas (Lindholm e Yellin, 1999).
O conjunto de instruções da linguagem Java é orientado a pilha (stack-based) (En-
gel, 1999). A fim de elucidar essa característica, o trecho de código da Listagem 2.1
é descrito a seguir. Esse trecho de código computa a soma de dois valores inteiros
(4 e 2). A primeira linha é uma instrução bipush que consiste em estender (sign-
extend) seu operando, nesse caso o byte 4, para um inteiro representado por meio
de 4 bytes e colocar esse valor na pilha de operandos, conforme demonstrado na
Figura 2.8(a). A instrução seguinte realiza a mesma operação para o byte 23 . A si-
tuação da pilha de operandos após a execução dessas duas instruções aparece na
Figura 2.8(b). Posteriormente, a instrução iadd que é utilizada para realizar opera-
ções de adição envolvendo inteiros é executada, removendo os dois valores do topo
da pilha e substituindo-os pelo resultado, como na Figura 2.8(c). Conforme pôde ser
observado, tanto os valores dos operandos quando o resultado são, respectivamente,
obtidos e armazenado na pilha.


Listagem 2.1: Trecho de código que adiciona dois inteiros.
...
bipush 4
bipush 2
iadd
...


Outra característica dessas instruções é que a maioria possui informações sobre


o tipo de operando considerado explicitadas no mnemônico. O prefixo i da instrução
iadd, descrita anteriormente, indica que a pilha de operandos deve conter valores in-
teiros. Dessa forma, são definidas instruções para realizar a adição dos diversos tipos
primitivos suportados pela máquina virtual Java. Por exemplo, dadd é equivalente à
iadd, porém considera valores em ponto flutuante com precisão dupla (double).

(a) (b) (c)

Figura 2.8: Disposição da pilha de operandos após a execução das instruções da


Listagem 2.1.

3
A mesma disposição da pilha de operandos exibida na Figura 2.8(b) pode ser obtida por meio da
execução dos bytecodes iconst_4 e iconst_2 que consistem em colocar os valores inteiros 4 e 2 na
pilha.
CAPÍTULO 2. MÁQUINAS VIRTUAIS DE LINGUAGEM DE PROGRAMAÇÃO 20

2.6 Considerações Finais


Sistemas computacionais contêm várias camadas que se comunicam por meio de
interfaces. Quando uma determinada camada α precisa interagir com uma camada
β que possui uma interface diferente da esperada por α, um elemento intermediário
precisa ser introduzido. Tal elemento intermediário deve virtualizar a comunicação
entre as camadas envolvidas, abordando assim o mapeando das operações e estados
distintos. Implementações desse elemento intermediário são denominadas máquinas
virtuais e, conforme descrito no decorrer deste capítulo, elas vêm sendo introduzidas
em vários níveis de abstração dos sistemas computacionais e com diversos propósitos.
Devido à variedade de máquinas virtuais existentes, a apresentação foi fundamentada
em duas categorias, de acordo com o nível de abstração em que elas atuam: sistema
e processo.
Entre as máquinas virtuais de processo, as voltadas para suportar linguagens de
programação foram enfocadas, pois esse tipo será utilizado no contexto deste projeto
de pesquisa. Adicionalmente, com o propósito de fornecer um exemplo e descre-
ver as estruturas internas mais relevantes da máquina virtual que será utilizada, foi
apresentada uma visão geral da máquina virtual Java e seu conjunto de instruções
virtuais. Foram enfocadas as características necessárias para adequadamente com-
preender a proposta definida no Capítulo 4. Ademais, é importante ressaltar que
detalhes de implementação não foram mencionados. Foram descritos somente os
elementos presentes na especificação, cada uma das máquinas virtuais examinadas,
descritas no Capítulo 4, implementa esses elementos de forma distinta.
CAPÍTULO

3
Mapeamento Sistemático

Conforme uma determinada área de pesquisa evolui, o número de trabalhos cientí-


ficos abordando tal área, bem como tópicos diretamente relacionados e resultados
aumentam. Desse modo, torna-se mais complexa a obtenção de uma visão geral da
área. Nesse contexto, a Engenharia de Software baseada em Evidência (Evidence-
based Software Engineering) (Dybå et al., 2005) propõe a utilização de determina-
das metodologias para identificação, avaliação, interpretação e sintetização de infor-
mações relacionadas a estudos relevantes sobre uma determinada área de pesquisa
(Dybå e Dingsøyr, 2008). Essas metodologias são empregadas com o objetivo de se
minimizar as chances de obtenção de conclusões errôneas ou imprecisas.
Para obter uma visão geral dos tipos de funcionalidade, entre outras informações
(descritas mais detalhadamente na Seção 3.2), que vêm sendo pesquisadas e intro-
duzidas nas máquinas virtuais de linguagens de programação, um mapeamento sis-
temático (systematic mapping study)1 foi conduzido. Mapeamentos sistemáticos en-
volvem uma busca metódica por trabalhos, no decorrer deste capítulo referenciados
como estudos primários (primary studies) (Kitchenham, 2004), abordando questões
previamente estabelecidas em um protocolo.
O principal objetivo de estudos secundários como mapeamentos sistemáticos é
fornecer uma visão geral da área de pesquisa sendo considerada, identificando a
quantidade e, possivelmente, o enfoque e a qualidade dos estudos primários seleci-
onados, bem como os tipos de pesquisa que vêm sendo conduzidas e os resultados
correspondentes (Petersen et al., 2008). Mapeamentos sistemáticos são mais apropri-
1
Mapeamentos sistemáticos também podem ser denominados revisões de escopo (scoping review)
(Pretorius e Budgen, 2008).

21
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 22

ados para categorização dos elementos de uma área de pesquisa, pois a extração de
dados que ocorre durante a condução desses estudos é, geralmente, mais abrangente
(coarse-grained) do que a que acontece em revisões sistemáticas (Bailey et al., 2007).
Adicionalmente, mapeamentos sistemáticos são recomendados para identificação de
grupos de evidência (evidence clusters), para os quais futuras revisões sistemáticas
podem ser conduzidas, e carência de evidências (evidence gaps) em uma determinada
área de pesquisa (Pretorius e Budgen, 2008).
Na seção seguinte (3.1) descreve-se o processo empregado para condução de ma-
peamentos sistemáticos e na Seção 3.2 são apresentadas as questões de pesquisa que
motivaram a realização do mapeamento em questão. A busca e seleção dos estudos
primários é detalhada na Seção 3.3; os passos screening e keywording são apresen-
tados nas Seções 3.4 e 3.5, respectivamente; a descrição da categorização resultante
é apresentada na Seção 3.6. Uma visão geral dos resultados é provida na Seção 3.7
por meio do mapa resultante. Uma ferramenta de mineração de textos foi usada com
o intuito de reexaminar tanto a categorização quanto as categorias propostas, con-
forme ilustrado na Seção 3.8. Por fim, ameaças à validade e as considerações finais
são discutidas nas Seções 3.9 e 3.10

3.1 Processo para Condução de Mapeamentos Sistemáticos


Poucos estudos documentam mapeamentos sistemáticos no contexto de Engenharia
de Software (Juristo et al., 2004; Jørgensen e Shepperd, 2007; Bailey et al., 2007;
Pretorius e Budgen, 2008; Afzal et al., 2009), dado que somente recentemente uma
adaptação para tal processo foi proposta (Petersen et al., 2008). De acordo com a
adaptação de Petersen et al. (2008), os passos essenciais são: (i) definição das ques-
tões de pesquisa, (ii) busca por estudos primários, (iii) screening dos estudos pri-
mários, (iv) keywording dos resumos desses trabalhos e, por fim, (v) mapeamento e
extração das informações relevantes de acordo com as questões de pesquisa previ-
amente estabelecidas. Esses passos e a seqüência em que eles são aplicados são
ilustrados na Figura 3.1. Como pode ser observado, cada passo produz um resultado
intermediário, sendo que o resultado final é o mapeamento sistemático. Cada um dos
passos da Figura 3.1 é descrito nas subseções seguintes.

3.2 Definição das Questões de Pesquisa


As questões de pesquisa devem refletir o propósito do mapeamento sistemático, ou
seja, devem ser apropriadamente direcionadas aos dados da área de pesquisa que
serão enfatizados. O objetivo do mapeamento sistemático conduzido é: determinar as
características das máquinas virtuais de linguagem de programação que vêm sendo
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 23

mais pesquisadas e aprimoradas, bem como quais implementações de máquinas vir-


tuais são mais utilizadas nessas pesquisas. Portanto, as seguintes questões de pes-
quisa são provenientes desse objetivo:

Q1: Quais características/funcionalidade das máquinas virtuais de linguagem de


programação vêm sendo mais investigadas e aperfeiçoadas?

Q2: Quais implementações de máquinas virtuais de linguagem de programação são


mais utilizadas em contextos acadêmicos?

Figura 3.1: Visão geral da abordagem para condução de mapeamentos sistemáticos;


adaptada de Petersen et al. (2008).

Nesse passo também é necessário definir o escopo do mapeamento sistemático,


que descreve a população a ser considerada, intervenção e resultados esperados. De-
finidos como a seguir:

População: estudos primários sobre máquinas virtuais de linguagem de programa-


ção.

Intervenção: estudos primários que documentam a implementação de aperfeiçoa-


mentos introduzidos em máquinas virtuais de linguagem de programação. En-
tretanto, é importante mencionar que não é necessário que os estudos primários
apresentem alguma forma de validação relacionada à implementação proposta.
Essa restrição foi evitada dado que o propósito do mapeamento sistemático aqui
descrito é fornecer um ampla visão geral das pesquisas conduzidas, indepen-
dentemente do tipo de validação empregado. Caso somente os estudos primários
que apresentam validação fossem considerados, a abrangência do mapeamento
poderia ser comprometida.

Resultados esperados: visão geral das categorias de aprimoramentos introduzidos


em máquinas virtuais de linguagem de programação que vêm sendo mais in-
vestigadas e implementações de máquinas virtuais mais empregadas para im-
plementação de tais aprimoramentos. Com base nesse resultado, pretende-se
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 24

evidenciar a carência de pesquisas que vêm sendo conduzidas para aprimorar


ou introduzir funcionalidades que apóiem a condução de atividades de Teste de
Software.

3.3 Busca por Estudos Primários


Esse passo, basicamente, envolve a definição da string de busca e das bases de dados
eletrônicas a serem utilizadas. A fim de se obter uma ampla perspectiva e apropria-
damente fornecer evidências que apóiem o esclarecimento das questões de pesquisa
descritas anteriormente, as seguintes bases de dados eletrônicas foram consultadas,
pois, de acordo com Dybå et al. (2007), essas bases estão entre as mais relevantes no
contexto de Engenharia de Software:

• Compendex (www.engineeringvillage.com);

• ACM Digital Library (portal.acm.org);

• IEEEXplore (ieeexplore.ieee.org);

• Springer LNCS (www.springer.com/lncs); e

• ScienceDirect (www.sciencedirect.com);

A string usada nas buscas é formada por uma combinação das seguintes palavras-
chave e acrônimos: virtual machine, VM, high level language virtual machine e HLL
VM. Diversas combinações de palavras-chave foram testadas e a avaliação preliminar
dos resultados apoiou a determinação desse conjunto de palavras. Os mecanismos
de busca das bases de dados consideradas possibilitaram a busca por ocorrências
dessas palavras, combinadas por meio de operadores booleanos como AND e OR, tanto
no título quanto no resumo.
As palavras-chave selecionadas são bem gerais com o propósito de refletir o amplo
escopo desse tipo de estudo secundário. A utilização de palavras-chave mais restriti-
vas poderia prejudicar a abrangência do mapeamento sistemático aqui descrito.

3.4 Screening
Com o intuito de verificar quais estudos devem fazer parte do conjunto incluído no
mapeamento sistemático, a realização desse passo consiste em efetuar uma avalia-
ção dos estudos retornados por meio de critérios de inclusão e exclusão previamente
definidos (Petersen et al., 2008).
Durante a seleção dos estudos primários, as seguintes seções foram consideradas:
(i) título, (ii) resumo, (iii) introdução/contextualização e (iv) conclusões/considerações
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 25

finais. Assim, a seleção envolveu duas iterações para cada estudo primário selecio-
nado. A primeira iteração consistindo somente da leitura do título e do resumo. Para
estudos selecionados na primeira iteração, a segunda iteração abordou a leitura das
seções introdução/contextualização e conclusões/considerações finais, avaliando-as
de acordo com os critérios de inclusão e exclusão. Porém, para extrair informações
sobre qual a implementação de máquina virtual usada no estudo primário, freqüen-
temente, outras seções também tiveram que ser examinadas.
Os critérios de inclusão e exclusão apóiam a seleção de estudos relevantes e que
apropriadamente auxiliam no esclarecimento das perguntas propostas. No contexto
desse mapeamento sistemático, os estudos foram examinados de acordo com os se-
guintes critérios:

• Critérios de inclusão:

– disponibilidade de consulta do estudo primário por meio eletrônico utili-


zando mecanismos de busca por meio de palavras-chave.
– no caso de mais de um estudo primário reportando a mesma pesquisa, so-
mente o mais recente será considerado.
– caso o mesmo estudo primário descreva mais de um estudo, cada um de-
les será abordado separadamente e influenciará o mapeamento como um
estudo distinto.

• Critérios de exclusão:

– estudos primários que não abordam especificamente máquinas virtuais de


linguagem de programação; por exemplo, estudos primários que detalham
aprimoramentos introduzidos em máquinas virtuais de sistema.
– aprimoramentos que consistem somente na introdução de modificações no
conjunto de instruções virtual da máquina subjacente.
– estudos primários que não descrevem a implementação do aprimoramento
proposto.
– estudos primários que descrevem a implementação de aperfeiçoamentos
cuja introdução não implica a alteração da máquina virtual em questão,
somente utilizam, direta ou indiretamente, a funcionalidade provida por tal
ambiente de execução.
– outros estudos secundários; por exemplo, revisões sistemáticas ou outros
mapeamentos sistemáticos.
– estudos primários como relatórios técnicos, trabalhos em andamento, pôs-
teres, apresentações e painéis (“grey” literature). Alguns dos motivos para
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 26

não considerar esses estudos primários são: (i) a avaliação da qualidade


desses tipos de trabalho é complexa e (ii) considerar esses materiais elevaria
o número de estudos primários a ser analisado.

Não foram estabelecidos limites para as datas de publicação dos artigos. Na Ta-
bela 3.1 é apresentada uma visão geral do total de estudos retornados por cada uma
das bases de dados, a quantidade inicialmente selecionada e o conjunto final, formado
por 128 estudos primários.

Tabela 3.1: Visão geral dos artigos retornados por cada base de dados eletrônica, total
de artigos pré-selecionados e de artigos selecionados.

IEEE 309
Springer 640
ACM 1554
Compendex 1395
ScienceDirect 1123
T OTAL 5021
Pré-selecionados 142
Seleção final 128

3.5 Keywording
Esse passo enfoca a classificação e categorização dos estudos selecionados anteri-
ormente. Para tal, a princípio, os resumos são lidos e palavras-chave que refle-
tem a contribuição apresentada pelo estudo primário são destacadas. Dessa forma,
identifica-se o contexto no qual a contribuição em questão se insere. Posteriormente,
os conjuntos de palavras-chave extraídos dos estudos são combinados e analisados,
possibilitando uma abrangente compreensão da área de pesquisa como um todo. A
partir dessa combinação e análise, é possível estabelecer um conjunto de categorias
que representam a população em questão (Petersen et al., 2008). Uma visão geral da
abordagem usada para construção das categorias é apresentada na Figura 3.2.
Durante a condução desse passo, deficiências apresentadas pelos resumos dificul-
taram a aplicação da abordagem da Figura 3.2. De acordo com Brereton et al. (2007),
normalmente, resumos de estudos pertencentes ao domínio de Engenharia de Soft-
ware são incompletos. Isso dificulta a condução de estudos secundários, dado que a
omissão de informações torna complexa a determinação e apuração da relevância dos
estudos primários. Uma abordagem para melhorar a apresentação e organização das
informações contidas nos resumos é a utilização de resumos estruturados (structured
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 27

Figura 3.2: Abordagem usada para criação das categorias; adaptada de Petersen et al.
(2008).

abstracts) (Budgen et al., 2008). Contudo, apesar da abordagem baseada em evidên-


cia ter sido recentemente adotada no domínio de Engenharia de Software, nenhum
dos estudos primários selecionados possui resumo estruturado. Com isso, estudos
que apresentam resumos deficientes tiveram as seções introdução e conclusões lidas.
Alguns problemas encontrados durante a condução desse mapeamento sistemá-
tico, principalmente em relação à aplicação dos passos Screening e Keywording, são:

• Omissão de informações no resumo como, por exemplo, implementação de má-


quina virtual em que a funcionalidade, aprimoramento, extensão, etc., foi intro-
duzida. Além disso, vários estudos mencionam a implementação de máquina
virtual utilizada porém não explicitam a versão.

• Alguns resumos dificultaram a identificação de palavras-chave por meio da uti-


lização de sinônimos não usuais.

• Poucos estudos primários apresentam uma lista de palavras-chave (que facilita


a categorização inicial do estudo em questão).

3.6 Categorização Resultante


Cada um dos estudos primários foi mapeado de acordo com o seu tipo de contribuição.
Visto que não há nenhuma taxonomia que engloba os vários tipos de melhorias repor-
tadas nos estudos selecionados, todas as categorias propostas para esse mapeamento
são descritas nas próximas seções. Adicionalmente, alguns estudos pertencentes às
categorias são descritos a fim de elucidar as pesquisas que vêm sendo conduzidas. É
importante mencionar que determinados estudos pertencem a mais de uma categoria.
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 28

3.6.1 Otimização
Apesar dos benefícios proporcionados por máquinas virtuais, a utilização desse tipo
de tecnologia implica na introdução de uma camada adicional, resultando em ques-
tões de desempenho. Determinadas construções das linguagens de programação, as-
sim como certos mecanismos implementados nas máquinas virtuais (gerenciamento
de memória, por exemplo), também afetam negativamente o tempo de execução.
Dessa forma, um tópico amplamente investigado no contexto de máquinas virtuais
são técnicas para aprimorar o desempenho. Tais técnicas no decorrer deste capítulo
serão referidas como técnicas de otimização.
Conforme descrito no Capítulo 2, máquinas virtuais utilizam, basicamente, duas
abordagens para execução: interpretação e compilação. Em vista disso, existem téc-
nicas de otimização para essas duas abordagens. As técnicas de otimização mais
difundidas para interpretadores são: threaded code (Bell, 1973), super-instruções
(Ertl e Gregg, 2004) e utilização de arquiteturas baseadas em registradores (Shi et al.,
2008). Considerando compilação, a técnica mais utilizada é a compilação just-in-time
(JIT) (Aycock, 2003). Estudos primários nessa categoria enfocam o desenvolvimento
de técnicas para mitigar o custo computacional dessas abordagens de execução e de
determinadas construções da linguagem subjacente (strings e manipulação de exce-
ções, por exemplo), melhorando assim o desempenho observável por parte das má-
quinas virtuais. A seguir, alguns desses estudos são descritos.
A máquina virtual Java utiliza pilhas (stacks) para armazenar variáveis locais
e resultados parciais. Objetos, no entanto, são alocados e armazenados na heap
(Lindholm e Yellin, 1999). A fim de reduzir o custo computacional relacionado à alo-
cação e liberação de memória Molnar et al. (2009) propõem que alguns objetos sejam
alocadas na pilha. Para determinar quais objetos podem ser alocados na pilha um
algoritmo de escape analysis foi implementado. A implementação de máquina virtual
Java utilizada nesse estudo é a CACAO (CACAOVM, 2010). De acordo com os autores,
a implementação dessa estratégia resultou em melhorias de desempenho de até 69%.
Há compiladores JIT que recompilam todo o código dos métodos relacionados a
uma classe. Contudo, são mais comuns implementações que empregam estratégias
para determinar quais trechos de código devem ser recompilados (hot sets) e o quanto
deve ser despendido na compilação. Assim, quanto mais invocado um trecho de
código, mais otimizado torna-se. Isso também evita a sobrecarga de ter que compilar
todo o código da aplicação. Gu e Verbrugge (2008) descrevem a implementação de
uma estratégia de recompilação adaptativa baseada em fases. A estratégia consiste
na coleta de informações offline ou online (durante a execução) que são utilizadas para
classificar os trechos de código em fases e, a partir dessa classificação, determinar
quais trechos devem ser recompilados e em que nível de otimização. Segundo os
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 29

autores, a implementação dessa estratégia na Jikes Research Virtual Machine (RVM)


(Alpern et al., 2005) resultou em melhorias de desempenho de até 21%.
Strings são um tipo de estrutura de dados utilizada em praticamente todos progra-
mas. Apesar dessa importância, elas são implementadas de maneira ineficiente em
várias máquinas virtuais Java (Renouf, 2009; Sun Microsystems, Inc., 2010), sendo
compostas por dois objetos distintos: (i) metadados como, por exemplo, o tamanho
da string são armazenados no objeto que representa a string; (ii) os caracteres que
compõem a string são armazenados em um array. Essa separação, conforme descrito
por Häubl et al. (2008), causa uma sobrecarga desnecessária. Häubl et al. (2008)
propõem uma implementação que agrupa os atributos em somente um objeto. Após
a introdução dessa versão otimizada na HotSpot (Sun Microsystems, Inc., 2010), a
utilização de memória e o tempo de execução foram reduzidos em aproximadamente
19% e 8%, respectivamente.

3.6.2 Gerenciamento de Memória Automatizado


Um dos benefícios das máquinas virtuais é o gerenciamento de memória automati-
zado. Esse mecanismo é parte essencial das implementações de máquinas virtuais
contemporâneas como Java, Python e Ruby. O elemento responsável por recuperar
a memória preenchida por recursos que não são mais utilizados ou alcançáveis (gar-
bage) é comumente denominado “coletor de lixo” (garbage collector). Existem diversas
abordagens para implementação desse mecanismo. Em cada uma delas, a identi-
ficação das regiões da memória e recursos que devem ser liberados varia; as três
mais aplicadas são: contagem de referências (reference counting), mark-and-sweep e
copying (Jones e Lins, 1996). Devido às diferenças entre elas, implementações produ-
zem resultados distintos principalmente em termos de tempo de pausa (pause time),
ou seja, período no qual os recursos não alcançáveis são identificados e eliminados
da memória. Conforme evidenciado pelos estudos primários dessa categoria, várias
pesquisas têm sido conduzidas com o propósito de diminuir o tempo de coleta.
No contexto de aplicações de tempo real, as interrupções ocasionadas pelo coletor
de lixo devem ser minimizadas para que as restrições temporais sejam satisfeitas.
Mais especificamente, operações de coleta devem ser controladas com o propósito de
possibilitar que as aplicações executem de acordo com o tempo estipulado. Assim,
as atividades de coleta de lixo devem ser controláveis, como breves unidades escalo-
náveis. Goh et al. (2005) descrevem a implementação de um coletor de lixo com tais
características na máquina virtual MONO (Ximian, 2010). É importante mencionar
que esse estudo primário também pertence à categoria tempo real (Subseção 3.6.10).
Alguns estudos têm constatado que o desempenho dos algoritmos de coleta de
lixo é dependente do comportamento das aplicações (Soman et al., 2004). Com base
nessas observações, Soman e Krintz (2007) propõem uma abordagem que possibilita
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 30

a mudança de algoritmo em tempo de execução, de acordo com as características


apresentadas pela aplicação, ou por meio da utilização de anotações no código fonte
(annotation-guided). Usando a abordagem dinâmica, melhorias de até 22% em relação
ao desempenho foram obtidas. Por meio da aplicação das anotações no código fonte
aprimoramentos que variam de 21 a 24%, dependendo da quantidade de memória
alocada para a heap.
Em geral, os estudos primários dessa categoria descrevem modificações realizadas
nos algoritmos clássicos, melhorando o desempenho em determinadas circunstân-
cias. Muthukumar e Janakiram (2006), por exemplo, propõem alterações para possi-
bilitar que o algoritmo baseado em gerações possa ser devidamente usado no contexto
de multiprocessadores. Bacon e Rajan (2001), Levanoni e Petrank (2006) e Lin e Hou
(2009) propõem versões distintas do algoritmo de contagem de referências e Azatchi
et al. (2003) uma versão do mark-and-sweep.
Normalmente, o critério mais comum utilizado para determinar quando o sistema
de gerenciamento de memória deve ser invocado é baseado no espaço disponível na
heap. Quando esse esse espaço livre atinge um determinado limite mínimo, o sistema
de gerenciamento é invocado. Todavia, esse mecanismo apresenta algumas deficiên-
cias como, por exemplo: evita que, em alguns casos, as aplicações criem objetos em
momentos críticos da execução. Considerando o cenário mencionado anteriormente,
uma técnica para disparar o sistema de gerenciamento de memória (garbage collec-
tion triggering technique) denominada MicroPhase é apresentada em um dos estudos
selecionados (Xian et al., 2007). A técnica é baseada nas seguintes observações: as
alocações de memória em programas Java, geralmente, ocorrem em fases e a fron-
teira entre as fases coincide com a ocorrência da morte2 da maioria dos objetos.
Dessa forma, de acordo com os autores, proativamente invocar o sistema de gerenci-
amento de memória durante a ocorrência dessas fases melhora o tempo de execução
das aplicações.

3.6.3 Depuração
Depuração (debugging) consiste na localização e correção de defeitos (Araki et al.,
1991; Myers et al., 2004). Determinados estudos enfocam a extensão da funcio-
nalidade provida por máquinas virtuais com o objetivo de automatizar e facilitar a
condução de atividades de depuração. Estudos que apresentam extensões desse tipo,
conforme o descrito a seguir, foram selecionados durante a condução do mapeamento
sistemático.
Algumas máquinas virtuais são implementadas na linguagem que elas suportam,
sendo denominadas máquinas virtuais meta-circulares. Alguns exemplos são a Jikes
2
Diz que um objeto está morto quando ele torna-se inalcançável e pode ser eliminado da memória.
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 31

RVM e a Maxine (Mathiske, 2008), ambas implementadas em Java. Esse tipo de má-
quina virtual dificulta a criação de depuradores, visto que vários níveis de abstração
devem ser considerados. Por exemplo, depurar uma máquina virtual Java implemen-
tada em Java requer acesso ao código fonte, bytecodes e código de máquina. Em
um dos estudos primários selecionados, Würthinger et al. (2010) descrevem a imple-
mentação do Maxine Inspector, um depurador de múltiplos níveis (multi-level) que é
voltado especificamente para suportar a depuração da Maxine.

3.6.4 Tolerância a Vazamentos de Memória


Vazamentos de memória (memory leak or leakage) ocorrem quando o programa em
execução aloca memória porém, por algum motivo, não libera devidamente essa me-
mória alocada (Larson e Miller, 2005). Caso a quantidade de memória não desalocada
aumente excessivamente, esse tipo de problema pode causar falhas e degradação de
desempenho. Determinados vazamentos de memória podem ser evitados pelo desen-
volvedor ou por mecanismos presentes nos ambientes de execução como, por exem-
plo, coletores de lixo. Todavia, nem todos os tipos de vazamentos de memória podem
ser abordados por coletores de lixo. Desse modo, alguns estudos propõem a imple-
mentação de funcionalidade adicional para tal fim.
Bond e McKinley (2008), por exemplo, relatam a implementação de uma funciona-
lidade para evitar a degradação de desempenho causada por objetos inativos porém
alcançáveis. Essa funcionalidade, implementada na Jikes RVM, pode ser sintetizada
como a seguir: (i) identificação dos objetos alcançáveis que, provavelmente, não serão
mais requisitados pelo programa em execução, (ii) segregação desses objetos, que são
removidos da memória e armazenados em disco, e (iii) caso necessário, subseqüente
ativação dos objetos em disco. Dessa forma, essa abordagem, análoga a paginação
usada por SOs, retarda a ocorrência de falhas ocasionadas por falta de memória.

3.6.5 Novas Construções de Linguagens de Programação


Linguagens de programação evoluem (Favre, 2005). Conforme essa evolução ocorre,
elementos relacionados com a linguagem também precisam ser alterados para se
ajustar as suas novas características e construções. Dada a intrínseca relação de
uma máquina virtual com a linguagem de programação suportada (Craig, 2005), ge-
ralmente, a introdução de uma nova construção só é possível caso a máquina virtual
em questão seja modificada. Nessa seção, são descritos os estudos primários que
abordam a introdução de novas construções em linguagens de programação acompa-
nhadas por alteração da máquina virtual subjacente.
A partir da versão 5.0, a linguagem Java possibilita a utilização de um modelo
de programação denominado Executor-Callable-Future. Aplicando esse modelo, de-
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 32

senvolvedores encapsulam trechos de código que podem ser executados de maneira


assíncrona em um objeto Callable que, posteriormente, é escalonado e executado
por meio de um objeto Executor. O resultado dessa execução é um objeto Future,
que pode ser usado pela thread corrente para obter o resultado da computação reali-
zada. Esse modelo é implementado por meio da utilização de várias interfaces; sendo
Future uma interface parametrizada (Niemeyer e Knudsen, 2005).
Essa atual implementação, de acordo com Zhang et al [46], apresenta algumas
deficiências: (i) toda a computação a ser realizada assincronamente deve ser encap-
sulada em um objeto, resultando em esforço adicional por parte do desenvolvedor; (ii)
o desenvolvedor deve selecionar o executor; e (iii) os vários objetos envolvidos afetam
negativamente o desempenho. Com o intuito de efetivamente minimizar essas defi-
ciências, Zhang et al. (2007a) implementaram a Directive-based Lazy Futures (DBL-
Futures). Por meio dessa abordagem, variáveis locais que potencialmente podem ser
executadas concorrentemente são anotadas com @future. Durante a execução, a
máquina virtual, com base nos recursos computacionais disponíveis, decide quais
futures devem ser executados de forma inline e os que devem ser associados a uma
thread. Adicionalmente, em outro estudo pertencente a essa categoria, Zhang et al.
(2007b) descrevem refinamentos introduzidos ao mecanismo de tratamento de exce-
ções da linguagem Java com o objetivo de apropriadamente suportar DBLFutures.

3.6.6 Profiling
Profiling é a coleta automatizada de informações relacionadas ao desempenho e com-
portamento de uma determinada aplicação. Estudos primários relacionados a intro-
dução dessa funcionalidade no contexto das máquinas virtuais existentes pertencem
a essa categoria.
Algumas máquinas virtuais utilizam online profiling e otimização dinâmica com o
intuito de melhorar a performance das aplicações. Entretanto, as informações cole-
tadas durante o profiling não são reutilizadas a fim de otimizar o desempenho de exe-
cuções subseqüentes, sendo descartadas ao final de cada execução. Com o propósito
de utilizar essas informações para otimização de subseqüentes execuções (cross-run),
Arnold et al. (2005) introduziram alterações na arquitetura da J9 e um repositório
para persistência de informações sobre as execuções anteriores. Dessa forma, as in-
formações do repositório podem ser posteriormente utilizadas para apoiar a realização
de otimizações seletivas (selective optimizations).

3.6.7 Programação Orientada a Aspectos


A programação orientada a aspectos (POA) foi introduzida no final da década de 90 a
fim de solucionar determinadas dificuldades relacionadas à separação apropriada de
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 33

interesses transversais (Kiczales e Mezini, 2005). Embora essa tecnologia tenha sido
bastante difundida desde então (Safonov, 2008; Laddad, 2009), o tópico mais pes-
quisado envolve a introdução de melhorias em nível de linguagem (Harbulot e Gurd,
2006; Ongkingco et al., 2006; Akai et al., 2009). Como resultado, as implementa-
ções atuais são baseadas em tecnologias existentes que não estão aptas a suportá-las
convenientemente.
AspectJ (Laddad, 2009), que consiste de uma extensão para possibilitar POA na
plataforma Java, é um exemplo de implementação dessa tecnologia. Dado que sua
implementação é baseada na reescrita de bytecodes (weaving) (Hilsdale e Hugunin,
2004), que não foram especificamente projetados para apoiar as construções da POA,
limitações de desempenho são apresentadas. Os estudos nessa categoria abordam
a introdução de suporte para construções da POA nas máquinas virtuais a fim de,
principalmente, melhorar o desempenho das aplicações que utilizam esse tipo de tec-
nologia.
Considerando a extensão AspectJ, join points são implementados por meio da ins-
trumentação de regiões do código fonte que correspondem aos pointcuts. Nas regiões
que podem ser determinadas somente em tempo de execução, pontos de verificação
são inseridos. Por questões de desempenho, é desejável que tais verificações se-
jam removidas. Em um dos estudos selecionados, Bockisch et al. (2004) descrevem
uma máquina virtual, denominada Steamloom, com determinadas extensões que a
tornam aspect-aware. Essas extensões podem ser sumarizadas como a seguir: in-
trodução de uma interface de programação de aplicativos (API), uma biblioteca para
manipulação de bytecodes e suporte para weaving.
cflow é outra construção da AspectJ que apresenta problemas de desempenho,
pois a forma como ela é implementada não reflete suas características dinâmicas.
Bockisch et al. (2006) descrevem uma abordagem para aprimorar o desempenho
dessa construção. A implementação da abordagem proposta explora e acessa es-
truturas internas da Steamloom como, por exemplo, a pilha de chamadas (call stack),
para melhorar o desempenho dessa construção em tempo de execução. Desse modo,
os autores propõem que o suporte para programação orientada a aspectos seja inte-
grado ao ambiente de execução, ou seja, à máquina virtual. Mais especificamente, na
abordagem proposta a otimização é realizada pelo compilador JIT integrado à Steam-
loom.

3.6.8 Sistemas Embarcados


Sistemas embarcados vêm sendo amplamente utilizados. Anteriormente, as lingua-
gens mais usadas para desenvolver esse tipo de sistema eram C e C++. Atualmente,
linguagens baseadas em máquinas virtuais, como Java, têm recebido crescente aten-
ção nesse contexto, tanto da comunidade acadêmica quanto da industrial. Lingua-
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 34

gens desse tipo têm sido enfocadas devido à questões de portabilidade.


Dado, porém, que a maioria desses sistemas embarcados devem ser projetados
para plataformas que apresentam recursos computacionais escassos, a adoção de lin-
guagens baseadas em máquinas virtuais resulta em alguns problemas. Por exemplo,
os dispositivos que executam esses sistemas contêm restrições relacionadas à me-
mória disponível, compelindo as máquinas virtuais voltadas para essas plataformas
à utilizarem pouca memória durante execução (low memory footprint). Além disso,
as abordagens de execução dessas máquinas virtuais também resultam em algumas
implicações: (i) interpretadores utilizam pouca memória em tempo de execução, mas
não apresentam bom desempenho; (ii) compiladores JIT apresentam desempenho su-
perior a interpretadores, no entanto, requerem mais memória em tempo de execução.
Estudos primários nessa categoria abordam os tipos de ajustes que, introduzidos nas
máquinas virtuais, possibilitam que elas sejam utilizadas como ambientes de execu-
ção em dispositivos embarcados.
Conforme mencionado, apesar da utilização de compiladores JIT resultar em bom
desempenho, o código otimizado introduz custos computacionais adicionais (overhead)
relacionados a sua recuperação em tempo de execução e, principalmente, ao seu ar-
mazenamento. A fim de amenizar esse problema, Zhang e Krintz (2004) propõem a
utilização de um framework para, dinamicamente, descarregar (unload) código otimi-
zado que não é utilizado freqüentemente, liberando assim recursos computacionais.
O framework identifica quais trechos de código devem ser descarregados e quando.

3.6.9 Segurança
Conforme descrito por Gong (2009), desde a introdução da linguagem Java, várias
pesquisas têm sido conduzidas com o propósito de aperfeiçoar a segurança provida
por máquinas virtuais. A categoria descrita nesta subseção agrupa estudos primários
que abordam a adição de funcionalidade aos mecanismos de segurança das máquinas
virtuais contemporâneas. Por exemplo, o estudo primário de Inoue e Forrest (2002)
que descreve uma estratégia para detecção de intrusões/anomalias denominada dy-
namic sandboxing.
A estratégia de Inoue e Forrest (2002), implementada na máquina virtual Open
Runtime Platform (ORP) (Cierniak et al., 2002), é voltada para plataformas que uti-
lizam profiling e compilação dinâmica. Nessa estratégia são utilizadas informações
obtidas por meio da máquina virtual subjacente a fim detectar anomalias em nível
de aplicação. A estratégia proposta consiste de duas atividades, a saber: geração
e execução do sandbox. Durante a primeira, um sandbox profile é construído por
meio da execução da aplicação utilizando uma máquina virtual instrumentada. As-
sim, cada sandbox é configurado de acordo com o comportamento apresentado pelo
contexto (aplicação) sendo considerado. Posteriormente, durante a segunda atividade
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 35

(execução do sandbox), comportamentos que não constam no sandbox profile são


considerados anômalos. Somente invocações de métodos são registras no sandbox
profile. A efetividade dessa implementação foi avaliada utilizando um “vírus” imple-
mentado na linguagem Java, denominado Strange Brew, e um servidor HTTP com um
“problema” de backdoor. Ambos foram apropriadamente detectados.

3.6.10 Tempo Real


Para que os requisitos temporais sejam atendidos em aplicações de tempo real, a pla-
taforma em questão tem de prover previsibilidade e desempenho satisfatório (Fidge,
1996; Shin e Ramanathan, 1994). Dessa forma, vários mecanismos das máquinas
virtuais devem ser adaptados para possibilitar que elas sejam empregadas como pla-
taformas para o desenvolvimento de aplicações de tempo real. Essa seção apresenta
alguns dos estudos primários que documentam pesquisas envolvendo essas adapta-
ções.
Em um dos estudos primários, Robertz (2003) descreve uma abordagem para atri-
buição de prioridades para alocação de memória. Dessa forma, requisições de me-
mórias classificadas como não-críticas podem não ser prontamente atendidas pelo
ambiente de execução. Assim, evita-se que um processo importante seja atrasado
devido à alocação de memória por um processo menos importante e, adicionalmente,
melhora-se a performance das aplicações, pois, o número de execuções do sistema de
gerenciamento de memória é reduzido.
A abordagem de Robertz (2003), fundamentalmente, consiste em garantir que pro-
cessos com alta prioridade não tenham sua execução atrasada devido as possíveis
interrupções causadas pelo sistema de gerenciamento de memória. Desse modo, du-
rante a execução de processos de alta prioridade, o sistema de gerenciamento de
memória é interrumpido. No período entre a ativação de outro processo de alta prio-
ridade, o sistema de gerenciamento de memória é “reativado” e é executado, caso seja
necessário. O restante do tempo é dividido entre a execução de processos de baixa
prioridade e do sistema de gerenciamento de memória. É importante mencionar que
para implementar a abordagem proposta não foi necessário introduzir nenhuma alte-
ração na sintaxe da linguagem Java, o mecanismo de manipulação de exceções é uti-
lizado com a semântica definida como a seguir: blocos envolvidos com uma cláusula
try-catch que captura a exceção NoNonCriticalMemoryException são considera-
dos não-críticos. Portanto, somente a máquina virtual Infinitesimal Virtual Machine
(IVM) foi alterada a fim de implementar o comportamento proposto. É importante
mencionar que esse estudo também pertence a categoria gerenciamento de memória
automatizado (Subseção 3.6.2).
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 36

3.6.11 Computação Distribuída


Várias linguagens proporcionam suporte para threads (Niemeyer e Knudsen, 2005;
Flanagan e Matsumoto, 2008; Lutz, 2009; Wampler e Payne, 2009), construção que
é geralmente utilizada para maximizar o throughput das aplicações. No entanto, atu-
almente, algumas aplicações possuem cargas de trabalho (workload) que não podem
ser devidamente executadas por um único processador. Uma forma de distribuir essa
carga de trabalho é por meio da migração de threads, possibilitando que a carga de
trabalho seja dividida e processada por várias máquinas virtuais em computadores
distintos. Durante a condução do mapeamento sistemático, estudos primários que
relatam a introdução de mecanismos para migração de threads em implementações
da máquina virtual Java foram selecionados como, por exemplo, o estudo de Ma et al.
(2009). Estudos enfatizando outro tipo de suporte para computação distribuída tam-
bém foram agrupados nessa categoria, a saber: estudos primários enfocando a intro-
dução de suporte para computação em grade (grid computing) (Stockinger, 2007).

3.6.12 Tolerância a Falhas


Para introdução de um mecanismo de tolerância a falhas é necessário: (i) prover
meios para, dinamicamente, inspecionar se uma determinada aplicação apresenta
o comportamento esperado e (ii) possibilitar que a aplicação, caso ela apresente um
comportamento diferente do esperado, se recupere desse estado errôneo e continue a
computação (Voas, 2001). Portanto, máquinas virtuais consistem de um “ambiente”
propício para introdução de tal funcionalidade, pois elas gerenciam vários atributos
relacionados à execução das aplicações.
Napper et al. (2003) modificam a máquina virtual Exact3 a fim de introduzir um
mecanismo, transparente ao usuário, de tolerância a falhas. O mecanismo imple-
mentado é baseado na execução concomitante de duas instâncias da máquina virtual
modificada; nesse contexto denominadas primária e backup. Caso a máquina virtual
primária apresente algum problema, a backup continua a execução. Para tal, as duas
executam as fontes de não-determinismo da plataforma (como exceções que podem
ser disparadas de forma assíncrona, acesso multithread a variáveis compartilhadas,
entre outras) de maneira idêntica.

3.6.13 Compartilhamento de Recursos entre Máquinas Virtuais


Dois estudos primários abordam o compartilhamento de recursos entre instâncias
da mesma máquina virtual. Em um dos estudos, a fim de aprimorar a utilização
3
Antes da versão 1.3.0, o Java Standard Development Kit (JDK) era distribuído com uma máquina
virtual denominada Exact. A partir da versão 1.3.0, essa máquina virtual foi substituída pela HotSpot.
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 37

total de memória em tempo de execução (footprint), Czajkowski et al. (2002) apresen-


tam duas implementações distintas da máquina virtual Java, uma que possibilita o
compartilhamento de bytecodes e outra que possibilita o compartilhamento de código
compilado e otimizado (executável). Wong et al. (2003) propõem o compartilhamento
de pacotes por meio da transformação desses pacotes em bibliotecas compartilhadas
cujas classes são representas em um formato que corresponde as representações in-
ternas da máquina virtual subjacente. Essa abordagem para compartilhamento de
pacotes foi implementada na máquina virtual HotSpot.

3.6.14 Teste de Software


A aplicação de critérios de teste sem o apoio de ferramentas automatizadas tende
a ser uma atividade propensa a erros (Barbosa et al., 2007). Desse modo, várias
ferramentas foram implementadas com o intuito de automatizar diversos critérios
de teste (Delamaro et al., 1993; Vicenzi et al., 2003). Entretanto, poucos estudos
avaliam a introdução desse tipo de funcionalidade em máquinas virtuais de forma
a tirar proveito das características e das informações contidas nesses ambientes de
execução. Somente dois estudos com essas características foram selecionados.
Desenvolvedores utilizam informações sobre a cobertura do código para avaliar
a qualidade e completude dos casos de teste. Geralmente, a cobertura do código
sendo testado é obtida por meio da introdução de instrumentação. Porém, conforme
o número de entidades sendo examinadas aumenta, a quantidade de instrumenta-
ção inserida no programa acarreta em sobrecargas desnecessárias. Com o objetivo de
abordar esse problema, o estudo de Chilakamarri e Elbaum (2004) propõe duas estra-
tégias para facilitar a coleta de informações sobre a cobertura do código. A estratégia
denominada local disposal (LD) remove a instrumentação assim que os trechos ins-
trumentados são executados, evitando que o desempenho do programa sendo testado
seja prejudicado. Mais especificamente, a instrumentação é anulada (nullified) por
meio da modificação de bytecodes. A instrução responsável por atualizar a cobertura
do código é uma invocação de método estático (bytecode invokestatic) que, quando
anulada, é substituída pelo bytecode nop.
A outra estratégia, denominada collective disposal (CD), aprimora a LD por meio
da incorporação de informações oriundas de diversas instâncias do programa sendo
testado. Um canal de comunicação é usado para possibilitar a troca de informações
entre as várias instâncias da máquina virtual executando o programa. Cada instân-
cia tem um vetor de cobertura que indica se determinada entidade já foi executada
por outra instância. Caso o vetor indique que a entidade ainda não foi executada,
ela é executada de acordo com a estratégia LD. Caso contrário, a instrumentação é
removida. As duas estratégias foram implementadas na máquina virtual Kaffe (Kaffe,
2010).
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 38

A execução de conjuntos de casos de teste em sistemas que apresentam carência


de recursos computacionais é problemática. Os problemas resultantes são agravados
quando máquinas virtuais que utilizam compilação dinâmica são utilizadas, dado que
versões em código binário do corpo de cada método são mantidas na heap. A fim de
abordar esse problema, no outro estudo dessa categoria (Kapfhammer et al., 2005)
é descrita uma estratégia que estende a versão da Jikes RVM modificada por Zhang
e Krintz (2004) a fim de adaptativamente selecionar e descarregar (remover da heap)
trechos de código raramente executados dos conjuntos de casos de teste. De acordo
com os experimentos conduzidos pelos autores, o tempo de execução do conjunto de
casos de teste foi reduzido em aproximadamente 34% e o tamanho total dedicado para
armazenando de código binário na heap diminuiu em média 78%.

3.7 Mapeamento dos Estudos Primários e Análise


Nesta seção é apresentada uma síntese dos resultados do mapeamento sistemático
conduzido. A fim de facilitar a exibição e organização das informações, os acrônimos
da Tabela 3.2 são usados para fazer menção a algumas categorias.

Tabela 3.2: Categorias e seus respectivos acrônimos.

Categoria Acrônimo
Gerenciamento de Memória Automatizado GMA
Tolerância a Vazamentos de Memória TVM
Novas Construções de Linguagens de Programação NCLP
Programação Orientado a Aspectos POA
Sistemas Embarcados SE
Computação Distribuída CD
Tolerância a Falhas TF
Compartilhamento de Recursos entre Máquinas Virtuais CRMV

Na Tabela 3.3 são ilustradas as quantidades de publicações de cada categoria.


Como mencionado, alguns estudos primários foram classificados como pertencentes
a mais de uma categoria, portanto, a soma das freqüências exibidas na Tabela 3.3,
totalizando 153, é maior do que o número de estudos selecionados, 128 (Tabela 3.1).
Conforme pode ser observado, os tipos de aprimoramentos mais comumente intro-
duzidos em máquinas virtuais são relacionados às categorias otimização, GMA, SE,
tempo real e profiling. Em contraste, as categorias com a menor quantidade de estu-
dos primários são TVM, CRMV e Teste de Software; 2 estudos cada. Com base nessas
informações, pode-se considerar que, principalmente, as categorias otimização, GMA
e SE, que agrupam a maior quantidade de estudos, constituem grupos de evidência.
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 39

Similarmente, TVM, CRMV e Teste de Software podem ser considerados desertos de


evidência (evidence deserts) (Bailey et al., 2007) devido à carência de pesquisas nessas
áreas.
Pesquisadores têm demonstrado crescente interesse nas 5 categorias com o maior
número de estudos. Considerando os últimos 11 anos, a quantidade de estudos
concernentes a essas categorias aumentou, principalmente, no período entre 2005 e
2008, como demostrado na Figura 3.3. Por sua vez, as categorias com menos estudos
primários não apresentam nenhum indício de crescimento no número de publicações
abordando temas relacionados as suas respectivas áreas.

Tabela 3.3: Quantidade de estudos primários por categoria.

Otimização 34
GMA 33
SE 24
Tempo Real 13
Profiling 9
POA 8
Depuração 8
CD 7
TF 4
NCLP 4
Segurança 3
TVM 2
CRMV 2
Teste de Software 2
0 5 10 15 20 25 30 35

A base de dados eletrônica com mais estudos selecionados é a ACM, 62. As outras
bases, EngineeringVillage, Springer e IEEE, têm 38, 16, e 12 estudos pertencentes
ao conjunto final, respectivamente. Como descrito na Tabela 3.1, a base de dados
ScienceDirect também foi consultada, no entanto, como ela foi a última base de dados
a ser averiguada, os estudos retornados adequados aos critérios de inclusão já haviam
sido pré-selecionados durante a busca anterior na EngineeringVillage, que retorna
resultados de várias outras bases de dados. Uma visão geral da distribuição dos
estudos conforme suas respectivas bases de dados é exibida na Figura 3.4(a) e (c).
Os estudos primários são descritos em vários tipos de publicações. Encontram-
se publicações em conferências, workshops, journals, simpósios e capítulos de livros
entre os estudos selecionados. O tipo mais comum no contexto deste mapeamento
sistemático é publicação em conferência (34%) e a menor quantidade de publicações
aparece em workshops (6%). A quantidade de estudos pertencente a cada tipo é
apresentado nas Figuras 3.4(b) e (d).
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 40

7
Otimização
GMA
6 SE
Tempo Real
5 Profiling

4
Freqüência

0
8 9 0 1 2 3 4 5 6 7 8 9 0
199 199 200 200 200 200 200 200 200 200 200 200 201
Ano

Figura 3.3: Projeção das publicações nas 5 categorias com maior número de estudos
primários.

(a) (b)

ACM 62 Conferência 46
EngineeringVillage 38 Journal 33
Springer 16 Simpósio 25
IEEE 12 Capítulo de livro 16
ScienceDirect 0 Workshop 8
(c) (d)

Figura 3.4: Distribuição dos estudos de acordo com a base de dados e o tipo de
publicação: em (a) ilustra-se a porcentagem de estudos pertencentes a cada base de
dados considerada e em (c) as respectivas quantidades; em (b) é exibida a divisão dos
estudos de acordo com o tipo de publicação e em (d) o número de estudos de cada
tipo.
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 41

É importante ressaltar que, de acordo com critérios de inclusão descritos na Se-


ção 3.4, quando dois ou mais estudos primários reportando a mesma pesquisa foram
retornados somente o mais recente foi selecionado; independentemente do tipo de
publicação desses estudos. Por exemplo, a primeira versão do estudo de Baker et al.
(2007), denominada “Accurate Garbage Collection in Uncooperative Environments with
Lazy Pointer Stacks” e publicada como capítulo do Lecture Notes in Computer Science,
não faz parte da seleção final visto que uma versão atualizada também foi retornada.
A versão mais recente, denominada “Accurate Garbage Collection in Uncooperative En-
vironments Revisited” e publicada no journal Concurrency and Computation: Practice
and Experience (Baker et al., 2009), foi selecionada.
A subseção seguinte apresenta um gráfico que possibilita uma análise mais deta-
lhada do mapeamento sistemático resultante, realçando grupos de evidência e deser-
tos e distribuição dos estudos de acordo com as categorias.

3.7.1 Mapa
O termo faceta é empregado para agrupar um conjunto de categorias. Facetas au-
xiliam na organização de um diagrama, denominado mapa (Afzal et al., 2009), que
sintetiza informações sobre as categorias e estudos primários pertencentes a um de-
terminado mapeamento sistemático. As facetas presentes no mapa desse mapea-
mento sistemático são: (i) tipo de aprimoramento introduzido, (ii) implementação de
máquina virtual usada no contexto do estudo primário e (iii) ano de publicação. O
mapa resultante da combinação dessas facetas, Figura 3.5, mostra como as catego-
rias e seus respectivos estudos estão distribuídos. Essa disposição apóia a análise
dos resultados enfocando a freqüência de publicações, auxiliando no determinação
da cobertura em cada campo de pesquisa e das implementações de máquina virtual
mais amplamente difundidas no meio acadêmico.
Como pode ser observado na Figura 3.5, a maioria dos estudos tem como pla-
taforma alvo implementações da máquina virtual Java; mais precisamente, 24 das
31 implementações. Dentre as implementações mais utilizadas encontram-se: Jikes
RVM, HotSpot, Kaffe, J9 e K Virtual Machine (KVM, 2010). Jikes RVM foi utilizada
em pelo menos um estudo pertencente a cada categoria; com exceção das catego-
rias segurança, tempo real e compartilhamento de recursos. Adicionalmente, ela foi
usada na maior parte dos estudos das categorias otimização, gerenciamento de me-
mória e POA. As outras máquinas virtuais, Objective Caml Virtual Machine (OCVM),
GForth, Tool Command Language Virtual Machine (TclVM), e SICStus, suportam as
linguagens Objective Caml (OCaml) (OCaml, 2010), Forth (Rather et al., 1996), Tool
Command Language (Tcl) (Tcl, 2010), e Prolog (SICStus, 2010), respectivamente. Má-
quinas virtuais voltadas para suportar mais de uma linguagem, como CLR e MONO,
também foram utilizadas em alguns estudos.
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 42

Figura 3.5: Mapa contendo a distribuição dos estudos de acordo com as facetas.
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 43

3.8 Categorização e Classificação por meio da Ferramenta PEx


Durante a condução de mapeamentos sistemáticos, alguns passos implicam na rea-
lização de atividades custosas em termos de esforço e tempo despendido, além disso,
elas requerem conhecimento do domínio sendo considerado. Duas atividades que
apresentam tais características são: (i) a criação do conjunto de categorias com base
nas palavras-chave e (ii) a classificação de tais estudos nas categorias. Visto que os re-
sultados dessas duas atividades podem ser subjetivos, variando assim de acordo com
os pesquisadores envolvidos, a seguir apresenta-se uma comparação dos resultados
descritos anteriormente com resultados obtidos por meio da utilização de uma abor-
dagem que é fundamentada em uma ferramenta de mineração visual de textos. Tal
comparação é descrita a fim de reexaminar tanto a categorização quanto classificação
propostas bem como fornecer evidências relacionadas à correção de ambas.
A abordagem utilizada para realização da categorização e classificação de maneira
automatizada é proposta por Felizardo et al. (2010). Essa abordagem é denominada
mapeamento sistemático baseado em mineração visual de textos (systematic mapping
based on visual text mining, SM-VTM) e utiliza a ferramenta Projection Explorer (PEx)4
(Paulovich et al., 2007). Na abordagem de Felizardo et al. (2010), os três primeiros
passos são idênticos ao apresentado na Figura 3.1. Após a seleção dos estudos, para
cada um deles cria-se um arquivo .bib contendo título, resumo e, opcionalmente,
palavras-chave. A partir dessas informações, PEx determina o grau de similaridade
entre os estudos por meio da construção de uma matriz composta pelos termos que
ocorrem freqüentemente. Porém, preposições e outros termos que aparecem muito
freqüentemente mas não auxiliam na determinação da similaridade entre os estudos
são eliminados. Posteriormente, a ferramenta produz algumas representações que
facilitam a análise dos estudos.
Com o auxílio de um dos autores da abordagem mencionada, os arquivos .bib
dos 128 estudos primários foram submetidos à ferramenta PEx. Na Figura 3.6 (a) é
exibida a representação produzida pela ferramenta, ilustrando a similaridade entre
os estudos. Cada ponto é um estudo primário, regiões que concentram vários pontos
indicam a existência de similaridade entre tais estudos. A cor dos estudos é utilizada
para indicar os respectivos grupos. Essa representação é denominada cluster view.
Os grupos de estudos são categorizados por meio do estabelecimento de tópicos.
Para tal, os termos que possuem a maior covariância são selecionados (Felizardo
et al., 2010). Por exemplo, os tópicos collector, fly, garbage, on-the-, jikes, root, scan-
ning, reference e counting são usados para categorizar o grupo que contém estudos
relacionados a GMA, estudos de cor verde circunscritos na Figura 3.6 (b). Seme-
lhantemente, nas Figuras 3.6 (c) e (d) são apresentados tanto os grupos de estudos
4
http://infoserver.lcad.icmc.usp.br/infovis2/PEx
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 44

sobre depuração e POA quanto os seus respectivos tópicos. É importante enfatizar


que os tópicos ilustrados nas Figura 3.6 (b), (c) e (d) foram produzidos após algumas
intervenções do usuário com a finalidade de remover termos gerais como program,
execution e runtime.

(a) (b)

(c) (d)

Figura 3.6: Categorização e classificações geradas pela ferramenta PEx: (a) ilustra-
se a disposição em que os estudos foram organizados nas categorias de acordo com
a similaridade entre eles e grupos que contêm os estudos relacionados a GMA (b),
depuração (c) e POA (d).

A ferramenta na maioria dos casos identificou os estudos semelhantemente ao


mapeamento realizado sem o apoio da PEx. Entretanto, devido às deficiências apre-
sentadas por alguns dos resumos, conforme descrito na Seção 3.5, e complexidades
inerentes do domínio, determinados estudos não foram agrupados de forma apro-
priada, ou seja, explicitamente delimitados. Assim, conclui-se que a representação
gerada pela ferramenta pode contribuir atuando como um passo inicial para as ati-
vidades de categorização e classificação, dependendo do domínio sendo considerado.
Contudo, a utilização dessa abordagem para domínios mais complexos e que empre-
gam diversos nomes para o mesmo conceito demanda várias intervenções por parte
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 45

do usuário e amplo conhecimento do domínio.

3.9 Ameaças à Validade


A impossibilidade de se garantir que todos os estudos relevantes foram selecionados
é uma das ameaças à validade. É possível que alguns estudos tenham sido omitidos
visto que nem todas as bases de dados eletrônicas foram consultadas. Não obstante,
de acordo com Pretorius e Budgen (2008), a maioria dos estudos é publicada pela
IEEE e ACM, e a ScienceDirect indexa journals da Elsevier. Dado que essas três ba-
ses de dados eletrônicas foram consultadas, pode-se considerar que as chances de
algum estudo relevante não ter sido considerado foram mitigadas. Outra ameaça à
validade é que determinados estudos primários foram classificados em várias catego-
rias, afetando assim a contagem de freqüências e algumas análises; como ilustrado
na Tabela 3.3 e Figura 3.5, por exemplo.

3.10 Considerações Finais


No decorrer deste Capítulo foi apresentado o mapeamento sistemático conduzido a
fim de determinar quais características das máquinas virtuais vêm sendo mais in-
vestigadas e aperfeiçoadas, bem como quais implementações são mais amplamente
utilizadas em contextos acadêmicos para introdução desses aperfeiçoamentos. De
acordo com os resultados obtidos, vários tipos de aprimoramentos vêm sendo im-
plementados em diversas máquinas virtuais. A categorização dos tipos de aprimora-
mentos resultou em 14 categorias que abrangem desde adaptações para possibilitar
que máquinas virtuais sejam usadas em dispositivos embarcados até implementações
para compartilhamento de recursos entre várias instâncias de determinada máquina
virtual. Otimização é a categoria que agrupa mais estudos secundários. Assim, pode
se considerar que esse tipo de aprimoramento é o que vem sendo mais pesquisado
e implementado. Em contraste, entre as categorias com menos estudos encontra-se
Teste de Software, o que motiva a condução deste trabalho.
A maioria dos estudos primários foram publicados em conferências, e a base de
dados eletrônica com mais estudos selecionados é a ACM, 48%. Durante a leitura
desses estudos, 31 implementações de máquinas virtuais foram identificadas. Imple-
mentações da máquina virtual Java são as mais utilizadas, 24 das 31 mencionadas.
Conforme ilustrado no mapa resultante (Figura 3.5), a Jikes RVM é a implementa-
ção mais usada. É importante enfatizar que apesar da ampla adoção de linguagens
como Ruby e Python nenhum dos estudos selecionados estende implementações das
máquinas virtuais de tais linguagens.
Inicialmente, esse mapeamento sistemático foi conduzido como passo inicial para
CAPÍTULO 3. MAPEAMENTO SISTEMÁTICO 46

a condução de uma revisão sistemática. Todavia, a partir da análise dos estudos


selecionados, constatou-se que a realização de uma revisão sistemática enfocando
somente aprimoramentos pertencentes à categoria Teste de Software não seria eficaz,
dado que o tópico de interesse apresenta carência de evidências.
CAPÍTULO

4
Proposta

Este capítulo tem o objetivo de delinear o projeto de pesquisa proposto. Para tal, na
Seção 4.1 apresenta-se uma visão geral da pesquisa proposta, na Seção 4.2 é descrita
a funcionalidade que será implementada a fim de automatizar e facilitar a condução
de atividades de Teste de Mutação e na Seção 4.3 descreve-se o suporte proposto para
apoiar o teste de programas concorrentes. Na seção 4.4 são apresentadas as imple-
mentações de máquina virtual que foram examinadas, bem como as características
que influenciaram a seleção dessas implementações, as atividades conduzidas são
descritas na Seção 4.5 e as previstas e o cronograma do projeto na 4.6. Por fim, as
considerações finais são apresentadas na Seção 4.7.

4.1 Proposta de Projeto


Máquinas virtuais de linguagem de programação são uma tecnologia bem difundida
e utilizada tanto em contextos acadêmicos quanto industriais. Várias linguagens de
programação contemporâneas são voltadas para esses ambientes de execução geren-
ciados. Alguns exemplos são: Java, Ruby, Python e Erlang (Cesarini e Thompson,
2009). Devido a diversos benefícios como, por exemplo, gerenciamento dinâmico de
memória, segurança, gerenciamento de threads e compatibilidade multiplataforma,
linguagens baseadas nesses ambientes de execução vêm sendo cada vez mais adota-
das para o desenvolvimento de diversos tipos de sistemas de software.
A popularização dessa tecnologia é resultante, especialmente, da introdução da
plataforma Java. Embora isso tenha ocorrido durante a segunda metade dos anos 90,
atualmente, de acordo com a evidência fornecida pelo mapeamento sistemático apre-

47
CAPÍTULO 4. PROPOSTA 48

sentado no Capítulo 3, a máquina virtual Java ainda é a mais amplamente utilizada


em contextos acadêmicos. Conforme indicado pela categorização do mapeamento em
questão, implementações da máquina virtual Java são usadas para atuarem como
ambientes de execução para aplicações de diversos tipos, incluindo sistemas embar-
cados e de tempo real.
Outro fator importante é que, além da linguagem Java, várias outras linguagem
têm a máquina virtual Java como ambiente de execução, ou seja, são compiladas para
bytecodes; como Groovy e Scala (Wampler e Payne, 2009), por exemplo. Além disso,
outras linguagens foram portadas para esse ambiente de execução, dois exemplos
são: Ruby e Python, denominadas nesse contexto JRuby (Edelson e Liu, 2008) e
Jython (Pedroni e Rappin, 2002), respectivamente.
Apesar de tratar-se de uma tecnologia consolidada, nenhuma implementação de
máquina virtual possui funcionalidade voltada para automatizar e facilitar a condução
de certas atividades de Engenharia de Software. Ademais, com base nos resultados do
mapeamento sistemático realizado, nota-se que poucas pesquisas com esse propósito
vêm sendo conduzidas; somente 2 estudos primários dos 128 selecionados abordam
a introdução de funcionalidade adicional a fim de apoiar a realização de atividades de
teste de software. A maioria dos pesquisas compreende o desenvolvimento, avaliação
e implementação de melhorias não-funcionais como mecanismos de gerenciamento
de memória superiores.
Portanto, para que certas atividades de Engenharia de Software sejam devida-
mente conduzidas, tecnologias adicionais devem ser empregadas. Usualmente, essa
carência é suprida por ferramentas que implementam a funcionalidade necessária.
Todavia, em alguns contextos, a utilização de ferramentas implica na introdução de
características indesejadas. Por exemplo, considerando atividades de teste de soft-
ware, a utilização de ferramentas para determinar a cobertura do código pode envol-
ver a instrumentação do código sendo testado; resultando em aumento do tamanho
do código objeto.
Considerando as circunstâncias mencionadas anteriormente, este trabalho enfoca
atividades de teste de software, fundamentando-se na seguinte conjetura: caso as
máquinas virtuais fornecessem suporte para a realização de determinadas atividades
de teste, a quantidade de tecnologias envolvidas seria reduzida, facilitando a con-
dução dessas tarefas. Desse modo, pretende-se estudar quais características que,
introduzidas as máquinas virtuais existentes, possibilitam e facilitam a condução de
atividades de teste empregando técnicas como, por exemplo, o Teste de Mutação. Adi-
cionalmente, visto que máquinas virtuais Java são as mais usadas no contexto aca-
dêmico, pretende-se introduzir algumas das características propostas por este projeto
de pesquisa em uma implementação dessa máquina virtual.
A seguir, com o intuito de elucidar o tipo de estudo que será desenvolvido, são
CAPÍTULO 4. PROPOSTA 49

apresentadas as funcionalidades que serão implementadas. Um dos exemplos a se-


guir automatiza e facilita a realização de atividades de Teste de Mutação e o outro
apoia o teste de programas concorrentes.

4.2 Ambiente para Teste de Mutação


O suporte proposto para atividades de Teste de Mutação, essencialmente, consiste na
introdução de funcionalidade que torne possível: (i) a execução parcial de programas
e (ii) a comparação dos resultados de tais execuções parciais.
Considerando o Teste de Mutação, possibilitar a execução parcial de programas é
essencial, visto que executar o programa inteiro é custoso tanto em termos de tempo
de resposta quanto de recursos computacionais. Além disso, é importante obser-
var que programas que contêm interface gráfica dificultam a realização do Teste de
Mutação pois, devido aos vários elementos gráficos nesses casos, torna-se mais com-
plexo reproduzir as entradas definidas nos casos de teste. Por isso, tende-se a utilizar
o Teste de Mutação para o teste de unidade e integração (Delamaro et al., 2007),
não em todas as camadas ou entidades de um programa. No contexto deste projeto,
pretende-se enfocar o teste de unidade, mais especificamente, métodos.
Em relação às comparações de execuções, a abordagem mais usual é obter as
seqüências de caracteres enviadas pelos programas para os dispositivos de saída e
comparar as seqüências produzidas pelo programa original e pelos mutantes. Outra
é considerar somente os caracteres não brancos da seqüência (Delamaro et al., 2007).
Além dessas, outra abordagem é usar o código de retorno dos programas; valor que
indica se a execução terminou normalmente ou não. O aspecto inovador do ambiente
de mutação proposto é que, além das abordagens mencionadas, pretende-se empregar
elementos estruturais que compõem e definem o comportamento de máquinas virtuais
Java.
Conforme descrito na Seção 2.5, cada vez que um método é invocado, um frame
é criado. Esses frames contém uma pilha de operandos e um espaço de armaze-
namento voltado tanto para os parâmetros quanto para as variáveis definidas loca-
mente, como ilustrado na Figura 2.6. Propõe-se que esses elementos estruturais que
definem o comportamento de métodos sejam utilizados para determinar quando exe-
cuções da versão original de um determinado método e seus mutantes produzem ou
não o mesmo resultado. Além desses elementos locais, a heap e algumas das estru-
turas com escopo global alocadas nessa área, como o runtime constant pool, também
devem ser consideradas. A heap deve ser modificada com o intuito de possibilitar
a implementação da funcionalidade proposta dado que as mutações introduzidas lo-
calmente podem resultar em alterações que afetem elementos com escopo global na
máquina virtual como, por exemplo, variáveis de instância, objetos passados como
CAPÍTULO 4. PROPOSTA 50

parâmetro e os criados localmente. A alteração de constantes, entre outras muta-


ções, pode ocasionar em alterações no runtime constant pool, armazenado na área de
métodos.
Com a introdução da funcionalidade proposta, antes da execução de cada método,
um snapshot do estado atual da pilha é obtido. Após a execução, outro snapshot
contendo o estado interno dos elementos locais associados ao frame do método em
questão e da heap são armazenados. Esses snapshots, no contexto dessa funcionali-
dade, são utilizados com o propósito de restaurar o estado da máquina virtual antes
da execução de cada mutante e para possibilitar que o estado resultante da execução
do método original seja comparado com o produzido pelos mutantes. Assim, a execu-
ção segue o fluxo normal até que um método que tenha sido mutado seja encontrado.
Quando tal método é encontrado armazena-se um snapshot do contexto antes da
execução, executa-se o método e, após a execução da última instrução do corpo do
método, um snapshot do contexto é capturado novamente. Porém, diferentemente do
primeiro snapshot, esse último contém o estado do frame do método subjacente.
A principal vantagem dessa abordagem, que utiliza métodos como unidades bá-
sicas, é que não é necessário executar o programa inteiro para decidir quando um
mutante deve ser morto. Por outro lado, é importante mencionar que é possível que
um caso de teste que diferencie dois métodos não chegue a distinguir os programas
se considerada sua execução completa.

4.3 Suporte para Teste de Programas Concorrentes


A implementação de aplicações concorrentes vem sendo enfatizada, visto que a mai-
oria dos processadores atuais é composto por mais de um núcleo (Pugh e Ayewah,
2007). Processadores desse tipo possibilitam que aplicações com alto nível de para-
lelismo, quando apropriadamente projetadas e desenvolvidas, tenham trechos simul-
taneamente executados, aprimorando assim o throughput e otimizando a utilização
dos recursos de processamento disponíveis (Goetz et al., 2006). Apesar desses bene-
fícios, o desenvolvimento de aplicações concorrentes é extremamente complexo. Adi-
cionalmente, o paralelismo obtido pelas aplicações concorrentes também apresenta
algumas desvantagens. A principal delas é o comportamento não-determinístico em
tempo de execução. Esse não-determinismo resulta na impossibilidade de replicar a
execução de maneira controlada, gerando imprevisibilidade, o que dificulta a condu-
ção e validação de algumas atividades de teste (Gong et al., 2007).
Além do suporte para condução de atividades de Teste de Mutação, pretende-se
integrar funcionalidade para facilitar a realização de atividades de teste considerando
sistemas concorrentes. A fim de que o teste desse tipo de programa seja apoiado
por parte das máquinas virtuais, objetiva-se avaliar e implementar a funcionalidade
CAPÍTULO 4. PROPOSTA 51

descrita a seguir:

Geração de diferentes seqüências de sincronização: nesse caso, a máquina virtual


se encarregaria de criar seqüências de escalonamento distintas a cada execu-
ção e, dessa forma, forçaria todos ou vários dos possíveis comportamentos da
aplicação. Essa funcionalidade representaria um passo adiante à reprodução
determinística de uma execução.

4.4 Implementações Examinadas


O mapa ilustrado na Figura 3.5 forneceu a evidência inicial para seleção das imple-
mentações de máquina virtual Java a serem consideradas. Dentre as implementa-
ções presentes no mapa foram examinadas as que satisfazem os seguintes critérios:
(i) disponibilidade (desenvolvida e distribuída sob modalidades de licenças de código
aberto), (ii) plataformas compatíveis, (iii) extensibilidade e (iv) aderência à especifica-
ção (Lindholm e Yellin, 1999). Com base nesses critérios, as seguintes implementa-
ções foram selecionadas e estudadas com o intuito de determinar a viabilidade técnica
de se introduzir as alterações requeridas para o desenvolvimento do projeto proposto.

JamVM foi implementada usando a linguagem C com alguns trechos dependentes de


plataforma implementados em binário e adere completamente à especificação.
A versão mais recente, 1.5.4, é de janeiro de 2010. Uma característica impor-
tante dessa implementação é que ela não possui um compilador JIT, porém, os
interpretadores disponíveis foram implementados incorporando várias técnicas
que representam o estado da arte, como stack-caching e direct-threading (Da-
vis e Waldron, 2003). Essa máquina virtual pode ser utilizada em mais de 10
plataformas (Robert Lougher, 2010).

Jikes RVM é, de acordo com a evidência provida pelo mapeamento sistemático, um


dos projetos mais difundidos no meio acadêmico. Tal projeto foi criado a partir
da máquina virtual Jalapeño (Alpern et al., 2005) que, inicialmente, foi desenvol-
vida por pesquisadores da International Business Machines (IBM). A Jikes RVM é
praticamente toda implementada na linguagem Java, assim a maior parte dessa
máquina virtual é independente de plataforma. Conforme descrito por Alpern
et al. (2005), ao contrário da maioria dos projetos de código aberto, o enfoque
do projeto Jikes RVM é proporcionar uma infra-estrutura que pode ser utilizada
e estendida para fins acadêmicos. A Jikes, ao contrário da JamVM, não possui
um modo de execução interpretado, tudo código a ser executado é compilado
pelo JIT dessa máquina virtual. A versão mais recente, 3.1.0, foi disponibilizada
em agosto de 2009.
CAPÍTULO 4. PROPOSTA 52

Maxine também é implementada na linguagem Java e, assim como a Jikes RVM, todo
o código é compilado antes de ser executado. A última versão dessa máquina vir-
tual é datada de abril de 2009. Uma das características mais importantes dessa
máquina virtual é a sua integração com um depurador, denominado Maxine Ins-
pector, desenvolvido de acordo com a arquitetura interna dessa implementação.
Porém, principal desvantagem dessa implementação é que ela é compatível so-
mente com plataformas 64 bits.

Algumas implementações não foram consideradas por apresentarem caracterís-


ticas inadequadas para o projeto em questão. The K virtual machine (KVM) (KVM,
2010), por exemplo, não foi considerada por implementar somente um subconjunto
da tecnologia Java, denominado Java Micro Edition (ME), que é voltado para dis-
positivos compactos como celulares e controles remotos. Implementações que não
passaram por atividades de manutenção nos últimos 3 anos não foram examinadas
pois foram consideradas projetos inativos.
Durante a avaliação das implementações, com o intuito de se obter uma visão geral
dos elementos arquiteturais mais importantes, alternou-se entre consultas ao código
fonte e à documentação, quando disponível. Para realização dessas duas atividades
os padrões de engenharia reversa denominados Read All the Code in One Hour e Skim
the Documentation, definidos por Demeyer et al. (2002), foram aplicados.
O padrão Read All the Code in One Hour foi aplicado com o objetivo de avaliar a
qualidade e a complexidade, entre outras propriedades, do código fonte. Tal avaliação
é realizada por meio de uma intensiva revisão do código fonte, extraindo-se uma im-
pressão inicial da qualidade e informações sobre como alguns elementos estruturais
importantes estão implementados. O padrão originalmente sugere que todo o código
seja lido em uma hora. No entanto, devido à complexidade e o tamanho do código
fonte das máquinas virtuais examinadas, o padrão foi aplicado pelo menos 3 vezes
para cada implementação.
O padrão Skim the Documentation foi aplicado a fim de avaliar a relevância da
documentação disponível. A aplicação do padrão Skim the Documentation resulta
na obtenção de informações, em alto nível de abstração, sobre a implementação.
Tais informações foram usadas para validar e complementar as informações de baixo
nível de abstração obtidas com a utilização do padrão Read All the Code in One Hour.
Porém, somente a Jikes RVM contém documentação, distribuída juntamente com o
código fonte. Assim, esse padrão foi aplicado somente para esse caso.
O outro padrão aplicado Do a Mock Installation (Demeyer et al., 2002), consistiu
na instalação das máquinas virtuais examinadas com o objetivo de detectar possíveis
problemas de compatibilidade e dependências. Apesar da complexidade dos processos
de instalação, nenhuma implementação apresentou problemas.
CAPÍTULO 4. PROPOSTA 53

As implementações foram avaliadas, principalmente, de acordo com a facilidade de


se introduzir as funcionalidades propostas. Conforme descrito anteriormente, as fun-
cionalidades envolvem a introdução de modificações em vários elementos estruturais.
Portanto, determinadas características das implementações que dificultam a introdu-
ção das melhorias propostas também foram consideradas. Por exemplo, apesar dos
benefícios de compiladores JIT como os apresentados pela Jikes RVM e Maxine, a
complexidade e o acomplamento resultante da introdução desse mecanismo dificul-
tam a introdução de uma funcionalidade conforme a descrita na Seção 4.2. Após a
condução das atividades mencionadas, determinou-se que a JamVM apresenta ca-
racterísticas mais favoráveis à introdução das funcionalidades propostas.

4.5 Atividades Realizadas


Foram conduzidas tanto atividades técnicas requeridas para concretização deste pro-
jeto quanto atividades exigidas pelo Programa de Pós-Graduação. A seguir, cada uma
das atividades realizadas é descrita.

Estudo detalhado da especificação da máquina virtual Java: fez-se necessário co-


nhecer a organização e os vários elementos que compõem a estrutura interna
da máquina virtual Java. A fim de se obter tal conhecimento, a especificação
dessa máquina virtual (Lindholm e Yellin, 1999) foi analisada durante o seguinte
período: junho de 2009 a fevereiro de 2010. Adicionalmente, investigou-se a im-
plementação dos elementos descritos na especificação nas seguintes máquinas
virtuais: JamVM, Jikes RVM e Maxine. Durante essa investigação observou-se
que no caso da Jikes RVM e da Maxine as implementações das estruturas des-
critas são, normalmente, diferentes; no entanto, a nomenclatura utilizada, na
maioria das vezes, é compatível com a proposta pela especificação. Por meio
da especificação1 também foi possível obter informações sobre o conjunto de
instruções (bytecodes) considerado pelas máquinas virtuais Java.

Seleção das implementações a serem examinadas: tal atividade, inicialmente, se-


ria conduzida de maneira independente, ou seja, várias implementações seriam
avaliadas e classificadas de acordo com as vantagens e possíveis desvantagens,
perceptíveis por meio da avaliação da arquiteura e código-fonte subjacentes. A
partir dessa avaliação, a máquina virtual alvo seria selecionada. No entanto,
optou-se pela não realização dessa tarefa e, ao invés disso, a seleção foi base-
ada no resultado do mapeamento sistemático conduzido. Mais específicamente,
dada a abrangência do mapeamento, pode-se considerar que os estudos mais
1
Literatura adicional como, por exemplo, o livro de Engel (1999), também foi consultada.
CAPÍTULO 4. PROPOSTA 54

relevantes foram retornados, selecionados e categorizados. Assim, somente im-


plementações presentes no mapeamento sistemático foram avaliadas. A seleção
final é composta pelas implementações descritas na Seção 4.4.

Condução de uma revisão bibliográfica: essa atividade foi realizada como um ma-
peamento sistemático (descrito na Seção 3), possibilitando que os passos reali-
zados possam ser replicados por outros pesquisados.

Definição dos aprimoramentos que devem ser implementados: os aprimoramen-


tos propostos anteriormente na versão inicial do projeto submetido à Funda-
ção de Amparo à Pesquisa do Estado de São Paulo (FAPESP) foram refinados.
Enfatizou-se o aperfeiçoamento da funcionalidade para apoiar a condução de
atividades de teste de mutação.

Cursar as disciplinas necessárias para cumprir os créditos exigidos pelo progra-


ma: os créditos de disciplinas exigidos pelo Programa de Pós-Graduação do De-
partamento de Ciências de Computação e Estatística do Instituto de Ciências
Matemáticas e de Computação (ICMC) começaram a ser obtidos em março de
2009, 4 disciplinas foram cursadas para obtenção dos créditos necessários.

4.6 Atividades Planejadas


1. Implementação dos aprimoramentos propostos;

2. Redação de artigos e relatórios técnicos;

3. Avaliação da máquina virtual resultante: após a implementação dos aper-


feiçoamentos, pretende-se avaliar a máquina virtual resultante. Por exemplo,
aplicações serão testadas por meio do ambiente para análise de mutantes pro-
posto.

4. Redação da tese: documentando as contribuições deste trabalho e descrições


das atividades desenvolvidas.

Tabela 4.1: Cronograma contendo as atividades a serem conduzidas.


1o sem. 2o sem. 1o sem. 2o sem. 1o sem. 2o sem. 1o sem. 2o sem.
Atividade 2009 2009 2010 2010 2011 2011 2012 2012

1
2
3
4
CAPÍTULO 4. PROPOSTA 55

4.7 Considerações Finais


A maioria das linguagens contemporâneas possui ambiente de execução baseado em
máquina virtual. O gerenciamento de memória, a criação e o escalonamento das thre-
ads, entre outros, são realizados pelas respectivas máquinas virtuais das linguagens
Java, Ruby e Python, por exemplo. Além disso, as máquinas virtuais representam
uma camada de abstração adicional que possibilita a portabilidade entre platafor-
mas. Todavia, apesar de tais recursos propícios para o desenvolvimento, as imple-
mentações das máquinas virtuais contemporâneas apresentam carência em relação à
características que auxiliam e automatizam a aplicação de técnicas de teste.
O teste de software é uma atividade essencial para detecção de erros e, portanto,
melhoria da qualidade do produto gerado. Considerando a relevância das ativida-
des de teste e o fato de que várias aplicações são desenvolvidas em linguagens que
possuem ambiente de execução baseado em máquina virtual, a realização das ativi-
dades de teste seria facilitada caso fosse fornecido algum tipo de suporte por parte
das máquinas virtuais. Apesar disso, pouco vem sendo desenvolvido nesse contexto,
a maioria das pesquisas envolvendo máquinas virtuais está relacionada à introdução
de melhorias no mecanismo de gerenciamento dinâmico de memória ou à alterações
visando a aperfeiçoar o desempenho desses ambientes de execução.
Este projeto tem o propósito de pesquisar as características que podem ser in-
troduzidas às máquinas virtuais Java a fim de facilitar e automatizar a condução
de atividades de teste e, principalmente, implementar algumas das características
propostas em uma das máquinas virtuais avaliadas. Com o objetivo de se fornecer
uma visão geral das características que serão pesquisadas e implementadas, foram
apresentados dois aprimoramentos; um que apoia a realização de atividades de teste
empregando a técnica de Teste de Mutação e outro que facilita o teste de aplicações
concorrentes.
Ao concluir este projeto, as seguintes contribuições são previstas: (i) conjunto de
funcionalidades para possibilitar que atividades de Teste de Software sejam mais fa-
cilmente conduzidas e (ii) uma implementação de máquina virtual Java com algumas
das funcionalidades propostas.
Referências Bibliográficas

A FZAL , W.; T ORKAR , R.; F ELDT, R. A Systematic Review of Search-based Testing for
Non-functional System Properties. Information and Software Technology, vol. 51,
n. 6, páginas 957–976, 2009.

A HO , A. V.; L AM , M. S.; S ETHI , R.; U LLMAN , J. D. Compilers: Principles, Techniques,


& Tools. 2 edição. Addison Wesley, 1009 páginas, 2007.

A KAI , S.; C HIBA , S.; N ISHIZAWA , M. Region Pointcut for AspectJ. In: Proceedings of
the 8th workshop on Aspects, components, and patterns for infrastructure software
(ACP4IS), ACM, páginas 43–48, 2009.

A LPERN , B.; A UGAR T, S.; B LACKBURN , S. M.; B UTRICO , M.; C OCCHI , A.; C HENG ,
P.; D OLBY, J.; F INK , S.; G ROVE , D.; H IND , M.; M C K INLEY, K. S.; M ERGEN , M.;
M OSS , J. E. B.; N GO , T.; S ARKAR , V. The Jikes Research Virtual Machine Project:
Building an Open-source Research Community. IBM Systems Journal, vol. 44,
n. 2, páginas 399–417, 2005.

A RAKI , K.; F URUKAWA , Z.; C HENG , J. A General Framework for Debugging. IEEE
Software, vol. 8, páginas 14–20, 1991.

A RNOLD , M.; W ELC , A.; R AJAN , V. T. Improving virtual machine performance using
a cross-run profile repository. ACM SIGPLAN Notices, vol. 40, n. 10, páginas 297–
311, 2005.

A UERBACH , J.; B ACON , D. F.; B LAINEY, B.; C HENG , P.; D AWSON , M.; F ULTON , M.;
G ROVE , D.; H AR T, D.; S TOODLEY, M. Design and Implementation of a Com-
prehensive Real Time Java Virtual Machine. In: Proceedings of the 7th ACM &
IEEE international conference on Embedded software (EMSOFT), ACM, páginas 249–
258, 2007.

56
REFERÊNCIAS BIBLIOGRÁFICAS 57

AYCOCK , J. A Brief History of Just-in-time. ACM Computing Surveys, vol. 35, n. 2,


páginas 97–113, 2003.

A ZATCHI , H.; L EVANONI , Y.; P AZ , H.; P ETRANK , E. An on-the-fly mark-and-sweep


garbage collector based on sliding views. In: Proceedings of the 18th annual ACM
SIGPLAN conference on Object-oriented programing, Systems, Languages, and Appli-
cations (OOPSLA), ACM, páginas 269–281, 2003.

B ACON , D. F.; R AJAN , V. T. Lecture Notes in Computer Science: European Conference


on Object-Oriented Programming (ECOOP) – Object-Oriented Programming, Capítulo:
Concurrent Cycle Collection in Reference Counted Systems, Springer Berlin/Hei-
delberg, páginas 207–235, 2001.

B AILEY, J.; B UDGEN , D.; T URNER , M.; K ITCHENHAM , B.; B RERETON , P.; L INKMAN ,
S. Evidence Relating to Object-Oriented software design: A Survey. International
Symposium on Empirical Software Engineering and Measurement, páginas 482–484,
2007.

B AKER , J.; C UNEI , A.; P IZLO , F.; V ITEK , J. Lecture Notes in Computer Science:
Compiler Construction, Capítulo: Accurate Garbage Collection in Uncooperative
Environments with Lazy Pointer Stacks, Springer Berlin/Heidelberg, páginas 64–
79, 2007.

B AKER , J.; C UNEI , A.; P IZLO , F.; V ITEK , J. Accurate Garbage Collection in Un-
cooperative Environments Revisited. Concurrency and Computation: Practice and
Experience, vol. 21, páginas 1572–1606, 2009.

B ARBOSA , E. F.; C HAIM , M. L.; V ICENZI , A. M. R.; D ELAMARO , M. E.; J INO , M.;
M ALDONADO , J. C. Introdução Teste de Software, Capítulo: Teste Estrutural,
Campus, páginas 47–76, 2007.

B ELL , J. R. Threaded code. Communications of the ACM, vol. 16, n. 6, páginas 370–
372, 1973.

B ER TOLINO , A. Software Testing Research: Achievements, Challenges, Dreams. In:


Future of Software Engineering (FOSE), IEEE Computer Society, páginas 85–103,
2007.

B OCKISCH , C.; H AUPT, M.; M EZINI , M.; O STERMANN , K. Virtual Machine Support
for Dynamic Join Points. In: Proceedings of the 3rd international conference on
Aspect-oriented software development (AOSD), ACM, páginas 83–92, 2004.

B OCKISCH , C.; K ANTHAK , S.; H AUPT, M.; A RNOLD , M.; M EZINI , M. Efficient Control
Flow Quantification. In: Proceedings of the 21st annual ACM SIGPLAN conference
REFERÊNCIAS BIBLIOGRÁFICAS 58

on Object-oriented programming, Systems, Languages, and Applications (OOPSLA),


ACM, páginas 125–138, 2006.

B OND , M. D.; M C K INLEY, K. S. Tolerating memory leaks. In: Proceedings of the 23rd
ACM SIGPLAN conference on Object-oriented Programming, Systems, Languages, and
Applications (OOPSLA), ACM, páginas 109–126, 2008.

B RERETON , P.; K ITCHENHAM , B. A.; B UDGEN , D.; T URNER , M.; K HALIL , M. Lessons
from Applying the Systematic Literature Review Process within the Software Engi-
neering Domain. Journal of Systems and Software, vol. 80, n. 4, páginas 571–583,
2007.

B UDGEN , D.; K ITCHENHAM , B. A.; C HAR TERS , S. M.; T URNER , M.; B RERETON , P.;
L INKMAN , S. G. Presenting Software Engineering Results using Structured Abs-
tracts: A Randomised Experiment. Empirical Software Engineering, vol. 13, pági-
nas 435–468, 2008.

CACAOVM The CACAOVM Project. Disponível em: http://www.cacaovm.org/,


acessado 5 de março, 2010.

C ARBONE , M.; Z AMBONI , D.; L EE , W. Taming Virtualization. IEEE Security and


Privacy, vol. 6, páginas 65–67, 2008.

C ESARINI , F.; T HOMPSON , S. Erlang Programming. O’Reilly Media, Inc., 496 páginas,
2009.

C HILAKAMARRI , K.-R.; E LBAUM , S. Reducing Coverage Collection Overhead with Dis-


posable Instrumentation. In: 15th International Symposium on Software Reliability
Engineering (ISSRE), páginas 233–244, 2004.

C IERNIAK , M.; L EWIS , B. T.; S TICHNOTH , J. M. Open Runtime Platform: Flexibility


with Performance using Interfaces. In: Proceedings of the 2002 joint ACM-ISCOPE
conference on Java Grande (JGI), ACM, páginas 156–164, 2002.

C ITRIX S YSTEMS I NC . The Xen Hypervisor. Disponível em: http://www.xen.org/,


acessado 5 de maio, 2010.

C LOCKSIN , W. F.; M ELLISH , C. S. Programming in Prolog: Using the ISO Standard. 5


edição. Springer, 293 páginas, 2003.

C OLBURN , T.; S HUTE , G. Abstraction in Computer Science. Minds and Machines,


vol. 17, n. 2, páginas 169–184, 2007.

C RAIG , I. D. Virtual Machines. Springer, 269 páginas, 2005.


REFERÊNCIAS BIBLIOGRÁFICAS 59

C ZAJKOWSKI , G.; D AYNÈS , L.; N YSTROM , N. Lecture Notes in Computer Science: Eu-
ropean Conference on Object-Oriented Programming (ECOOP) – Object-Oriented Pro-
gramming, Capítulo: Code Sharing among Virtual Machines, Springer Berlin/Hei-
delberg, páginas 269–270, 2002.

D AVIS , B.; WALDRON , J. A survey of optimisations for the java virtual machine.
In: Proceedings of the 2nd international Conference on Principles and Practice of
Programming in Java (PPPJ), ACM, páginas 181–183, 2003.

D ELAMARO , M. E.; B ARBOSA , E. F.; V ICENZI , A. M. R.; M ALDONADO , J. C. Intro-


dução Teste de Software, Capítulo: Teste de Mutação, Campus, páginas 77–118,
2007.

D ELAMARO , M. E.; M ALDONADO , J. C.; J INO , M.; C HAIM , M. L. Proteum: Uma Fer-
ramenta de Testes Baseada na Análise de Mutantes. In: Caderno de Ferramentas
do VII Simpósio Brasileiro de Engenharia de Software (SBES), páginas 31–33, 1993.

D EMEYER , S.; D UCASSE , S.; N IERSTRASZ , O. Object-Oriented Reengineering Patterns.


Morgan Kaufmann, 360 páginas, 2002.

D EUTSCH , L. P.; S CHIFFMAN , A. M. Efficient Implementation of the Smalltalk-80


System. In: Proceedings of the 11th ACM SIGACT-SIGPLAN symposium on Principles
of programming languages (POPL), ACM, páginas 297–302, 1984.

D YBÅ , T.; D INGSØYR , T. Strength of Evidence in Systematic Reviews in Software


Engineering. In: Proceedings of the Second ACM-IEEE international symposium on
Empirical software engineering and measurement (ESEM), ACM, páginas 178–187,
2008.

D YBÅ , T.; D INGSØYR , T.; H ANSSEN , G. K. Applying Systematic Reviews to Diverse


Study Types: An Experience Report. International Symposium on Empirical Soft-
ware Engineering and Measurement, páginas 225–234, 2007.

D YBÅ , T.; K ITCHENHAM , B. A.; J ØRGENSEN , M. Evidence-Based Software Enginee-


ring for Practitioners. IEEE Software, vol. 22, páginas 58–65, 2005.

D YBVIG , R. K. The Scheme Programming Language. 4 edição. The MIT Press, 512
páginas, 2009.

E DELSON , J.; L IU , H. JRuby Cookbook. O’Reilly Media, Inc., 224 páginas, 2008.

E NGEL , J. Programming for the Java Virtual Machine. Addison-Wesley Professional,


512 páginas, 1999.
REFERÊNCIAS BIBLIOGRÁFICAS 60

E R TL , M. A.; G REGG , D. Combining Stack Caching with Dynamic Superinstructi-


ons. In: Proceedings of the 2004 workshop on Interpreters, virtual machines and
emulators, ACM, páginas 7–14, 2004.

F AVRE , J.-M. Languages evolve too! Changing the Software Time Scale. Internatio-
nal Workshop on Principles of Software Evolution, páginas 33–44, 2005.

F ELIZARDO , K. R.; N AKAGAWA , E. Y.; F EITOSA , D.; M INGHIM , R.; M ALDONADO ., J. C.


An Approach Based on Visual Text Mining to Support Categorization and Classifi-
cation in the Systematic Mapping. 14th International Conference on Evaluation and
Assessment in Software Engineering (EASE), 2010.

F IDGE , C. It’s now or never. Crossroads, vol. 2, n. 3, páginas 4–5, 1996.

F LANAGAN , D.; M ATSUMOTO , Y. The Ruby Programming Language. O’Reilly Media,


Inc., 448 páginas, 2008.

G ALLARD , J.; L ÈBRE , A.; VALLÉE , G.; M ORIN , C.; G ALLARD , P.; S COTT, S. L. Lecture
Notes in Computer Science: Algorithms and Architectures for Parallel Processing, Ca-
pítulo: Refinement Proposal of the Goldberg’s Theory Springer Berlin/Heidelberg,
páginas 853–865, 2009.

G OETZ , B.; P EIERLS , T.; B LOCH , J.; B OWBEER , J.; H OLMES , D.; L EA , D. Java
Concurrency in Practice. Addison-Wesley Professional, 384 páginas, 2006.

G OH , O.; L EE , Y.-H.; K AAKANI , Z.; R ACHLIN , E. A Schedulable Garbage Collection


for Embedded Applications in CLI. International Workshop on Real-Time Computing
Systems and Applications, páginas 189–192, 2005.

G OLDBERG , R. P. Architecture of Virtual Machines. In: Proceedings of the Workshop


on Virtual Computer Systems, ACM, páginas 74–112, 1973.

G ONG , L. Java Security: A Ten Year Retrospective. Computer Security Applications


Conference, páginas 395–405, 2009.

G ONG , X.; WANG , Y.; Z HOU , Y.; L I , B. On Testing Multi-threaded Java Programs.
In: Proceedings of the Eighth ACIS International Conference on Software Engineering,
Artificial Intelligence, Networking, and Parallel/Distributed Computing (SNPD), IEEE
Computer Society, páginas 702–706, 2007.

G OSLING , J. Java Intermediate Bytecodes: ACM Sigplan Workshop on Intermediate


Representations (IR). ACM SIGPLAN Notices, vol. 30, n. 3, páginas 111–118, 1993.

G OSLING , J.; J OY, B.; S TEELE , G.; B RACHA , G. The Java Language Specification,
Capítulo: Exceptions. 3 edição Addison Wesley, páginas 297–307, 2005.
REFERÊNCIAS BIBLIOGRÁFICAS 61

G OUGH , J. Virtual Machines, Managed Code and Component Technology. Austra-


lian Software Engineering Conference, páginas 5–12, 2005.

G U , D.; V ERBRUGGE , C. Phase-based Adaptive Recompilation in a JVM. In: Pro-


ceedings of the sixth annual IEEE/ACM international symposium on Code generation
and optimization (CGO), ACM, páginas 24–34, 2008.

H ARBULOT, B.; G URD , J. R. A Join Point for Loops in AspectJ. In: Proceedings
of the 5th international conference on Aspect-oriented software development (AOSD),
ACM, páginas 63–74, 2006.

H ÄUBL , C.; W IMMER , C.; M ÖSSENBÖCK , H. Optimized Strings for the Java
HotSpotTM Virtual Machine. In: Proceedings of the 6th international symposium
on Principles and practice of programming in Java (PPPJ), ACM, páginas 105–114,
2008.

H ILSDALE , E.; H UGUNIN , J. Advice Weaving in AspectJ. In: Proceedings of the


3rd international conference on Aspect-oriented software development (AOSD), ACM,
páginas 26–35, 2004.

H OLMES , N. The Turning of the Wheel. Computer, vol. 38, páginas 98–99, 2005.

I ERUSALIMSCHY, R. Programming in Lua. 2 edição. Lua.org, 328 páginas, 2006.

I NOUE , H.; F ORREST, S. Anomaly Intrusion Detection in Dynamic Execution En-


vironments. In: Proceedings of the 2002 workshop on New security paradigms
(NSPW), ACM, páginas 52–60, 2002.

J ONES , R.; L INS , R. D. Garbage Collection: Algorithms for Automatic Dynamic Memory
Management. Wiley, 404 páginas, 1996.

J ØRGENSEN , M.; S HEPPERD , M. A Systematic Review of Software Development Cost


Estimation Studies. IEEE Transactions on Software Engineering, vol. 33, pági-
nas 33–53, 2007.

J URISTO , N.; M ORENO , A. M.; V EGAS , S. Reviewing 25 Years of Testing Technique


Experiments. Empirical Software Engineering, vol. 9, n. 1-2, páginas 7–44, 2004.

K AFFE Kaffe Virtual Machine. Disponível em: http://www.kaffe.org/, acessado 20


de abril, 2010.

K APFHAMMER , G. M.; S OFFA , M. L.; M OSSE , D. Testing in Resource Constrained


Execution Environments. In: Proceedings of the 20th IEEE/ACM international Con-
ference on Automated software engineering (ASE), ACM, páginas 418–422, 2005.
REFERÊNCIAS BIBLIOGRÁFICAS 62

K EEFE , D. D. Hierarchical Control Programs for Systems Evaluation. IBM Systems


Journal, vol. 7, n. 2, páginas 123–133, 1968.

K ICZALES , G.; M EZINI , M. Aspect-oriented Programming and Modular Reasoning.


In: Proceedings of the 27th international conference on Software engineering (ICSE),
ACM, páginas 49–58, 2005.

K ITCHENHAM , B. Procedures for Performing Systematic Reviews. Joint Technical


Report TR/SE-0401 (Keele) – 0400011T.1 (NICTA), Software Engineering Group - De-
partment of Computer Science, Keele University and Empirical Software Engineering
- National ICT Australia Ltd, Keele/Stas-UK and Eversleigh-Australia, 2004.

K OENIG , D.; G LOVER , A.; K ING , P.; L AFORGE , G.; S KEET, J. Groovy in Action.
Manning Publications, 696 páginas, 2007.

KVM The K Virtual Machine. Disponível em: http://java.sun.com/products/cldc/-


wp/, acessado 20 de abril, 2010.

L ADDAD , R. Aspectj in Action: Enterprise AOP with Spring Applications. 2 edição.


Manning Publications, 568 páginas, 2009.

L ARSON , D.; M ILLER , K. Silver Bullets for Little Monsters: Making Software More
Trustworthy. IT Professional, vol. 7, páginas 9–13, 2005.

L EVANONI , Y.; P ETRANK , E. An On-the-fly Reference-counting Garbage Collector


for Java. ACM Transactions on Programming Languages and Systems (TOPLAS),
vol. 28, n. 1, páginas 1–69, 2006.

L I , Q. Java Virtual Machine – Present and Near Future. International Conference


on Technology of Object-Oriented Languages, página 480, 1998.

L IN , C.-Y.; H OU , T.-W. Lecture Notes in Computer Science: Advances in Grid and Per-
vasive Computing, Capítulo: A Lightweight Cyclic Reference Counting Algorithm,
Springer Berlin/Heidelberg, páginas 364–359, 2009.

L INDHOLM , T.; Y ELLIN , F. The Java Virtual Machine Specification. 2 edição. Prentice
Hall, 496 páginas, 1999.

L UTZ , M. Learning Python: Powerful Object-Oriented Programming. 4 edição.


O’Reilly Media, Inc., 1216 páginas, 2009.

M A , M. J.; WANG , C.-L.; L AU , F. C. Cluster Computing, vol. 3, Capítulo: Delta


Execution: A Preemptive Java Thread Migration Mechanism, Apress, páginas 83–
94, 2009.
REFERÊNCIAS BIBLIOGRÁFICAS 63

M ALLACH , E. G. On the Relationship Between Virtual Machines and Emulators. In:


Proceedings of the Workshop on Virtual Computer Systems, ACM, páginas 117–126,
1973.

M ATHISKE , B. The maxine virtual machine and inspector. In: Companion to the
23rd ACM SIGPLAN Conference on Object-oriented programming, Systems, Langua-
ges, and Applications (OOPSLA), ACM, páginas 739–740, 2008.

M OLNAR , P.; K RALL , A.; B RANDNER , F. Stack Allocation of Objects in the CACAO
Virtual Machine. In: Proceedings of the 7th International Conference on Principles
and Practice of Programming in Java (PPPJ), ACM, páginas 153–161, 2009.

M UTHUKUMAR , R.; J ANAKIRAM , D. Yama: A Scalable Generational Garbage Collector


for Java in Multiprocessor Systems. IEEE Transactions on Parallel and Distributed
Systems, vol. 17, páginas 148–159, 2006.

M YERS , G.; S ANDLER , C.; B ADGETT, T.; T HOMAS , T. M. The Art of Software Testing.
Wiley, 256 páginas, 2004.

N AIK , S.; T RIPATHY, P. Software Testing and Quality Assurance: Theory and Practice.
Wiley, 468 páginas, 2008.

N APPER , J.; A LVISI , L.; V IN , H. A fault-tolerant java virtual machine. International


Conference on Dependable Systems and Networks, páginas 425–434, 2003.

N ELSON , P. A. A Comparison of PASCAL Intermediate Languages. In: Proceedings


of the 1979 SIGPLAN Symposium on Compiler Construction, ACM, páginas 208–213,
1979.

N IEMEYER , P.; K NUDSEN , J. Learning Java. O’Reilly Media, Inc., 984 páginas, 2005.

OC AML The OCaml Home Page. Disponível em: http://pauillac.inria.fr/ocaml/,


acessado 20 de abril, 2010.

O NGKINGCO , N.; AVGUSTINOV, P.; T IBBLE , J.; H ENDREN , L.; DE M OOR , O.; S ITTAMPA -
LAM , G. Adding Open Modules to AspectJ. In: Proceedings of the 5th international
conference on Aspect-oriented software development (AOSD), ACM, páginas 39–50,
2006.

P AULOVICH , F. V.; O LIVEIRA , M. C. F.; M INGHIM , R. The Projection Explorer: A


Flexible Tool for Projection-based Multidimensional Visualization. In: XX Brazi-
lian Symposium on Computer Graphics and Image Processing (SIBGRAPI), Sociedade
Brasileira de Computação (SBC), páginas 27–36, 2007.

P EDRONI , S.; R APPIN , N. Jython Essentials. O’Reilly Media, Inc., 304 páginas, 2002.
REFERÊNCIAS BIBLIOGRÁFICAS 64

P ETERSEN , K.; F ELDT, R.; M UJTABA , S.; M ATTSSON , M. Systematic Mapping Studies
in Software Engineering. 12th International Conference on Evaluation and Assess-
ment in Software Engineering (EASE), páginas 71–80, 2008.

P OPEK , G. J.; G OLDBERG , R. P. Formal Requirements for Virtualizable Third Gene-


ration Architectures. Communications of the ACM, vol. 17, n. 7, páginas 412–421,
1974.

P RETORIUS , R.; B UDGEN , D. A Mapping Study on Empirical Evidence Related to


the Models and Forms used in the UML. In: Proceedings of the Second ACM-
IEEE international symposium on Empirical software engineering and measurement
(ESEM), ACM, páginas 342–344, 2008.

P UGH , W.; AYEWAH , N. Unit Testing Concurrent Software. In: Proceedings of the
twenty-second IEEE/ACM international conference on Automated software enginee-
ring (ASE), ACM, páginas 513–516, 2007.

R ANDAL , A.; S UGALSKI , D.; T OETSCH , L. Perl 6 and Parrot Essentials. O’Reilly
Media, Inc., 304 páginas, 2004.

R ATHER , E. D.; C OLBURN , D. R.; M OORE , C. H. The Evolution of Forth. In: History
of programming languages — II, ACM, páginas 625–670, 1996.

R AU , B. R. Levels of Representation of Programs and the Architecture of Universal


Host Machines. In: Proceedings of the 11th annual workshop on Microprogramming
(MICRO), IEEE Press, páginas 67–79, 1978.

R ENOUF, C. Pro IBM


R
WebSphere
R
Application Server 7 Internals, Capítulo: The
IBM J9 Java Virtual Machine for Java 6, Apress, páginas 15–34, 2009.

R OBER T L OUGHER JamVM. Disponível em: http://jamvm.sourceforge.net/, aces-


sado 9 de junho, 2010.

R OBER TZ , S. G. Applying Priorities to Memory Allocation. ACM SIGPLAN Notices,


vol. 38, n. 2 supplement, páginas 108–118, 2003.

R OSENBLUM , M. The Reincarnation of Virtual Machines. Queue, vol. 2, n. 5, pági-


nas 34–40, 2004.

R OSENBLUM , M.; G ARFINKEL , T. Virtual Machine Monitors: Current Technology and


Future Trends. Computer, vol. 38, páginas 39–47, 2005.

S AFONOV, V. O. Using Aspect-Oriented Programming for Trustworthy Software Deve-


lopment. Wiley-Interscience, 338 páginas, 2008.
REFERÊNCIAS BIBLIOGRÁFICAS 65

S EAWRIGHT, L. H.; M AC K INNON , R. A. VM/370: A Study of Multiplicity and Useful-


ness. IBM Systems Journal, vol. 18, n. 1, páginas 4–17, 1979.

S HI , Y.; C ASEY, K.; E R TL , M. A.; G REGG , D. Virtual Machine Showdown: Stack


versus Registers. ACM Transactions on Architecture and Code Optimization, vol. 4,
n. 4, páginas 1–36, 2008.

S HIN , K.; R AMANATHAN , P. Real-time Computing: A New Discipline of Computer


Science and Engineering. Proceedings of the IEEE, vol. 82, n. 1, páginas 6–24,
1994.

SICS TUS SICStus Prolog: Leading Prolog Technology. Disponível em:


http://www.sics.se/isl/sicstuswww/site/index.html, acessado 21 de abril, 2010.

S IEH , V.; B UCHACKER , K. Lecture Notes in Computer Science, Capítulo: UMLinux -


A Versatile SWIFI Tool Springer Berlin/Heidelberg, páginas 599–603, 2002.

S MITH , J.; N AIR , R. Virtual Machines: Versatile Platforms for Systems and Processes.
Morgan Kaufmann, 656 páginas, 2005a.

S MITH , J. E.; N AIR , R. The Architecture of Virtual Machines. Computer, vol. 38,
n. 5, páginas 32–38, 2005b.

S OMAN , S.; K RINTZ , C. Application-specific Garbage Collection. Journal of Systems


and Software, vol. 80, n. 7, páginas 1037–1056, 2007.

S OMAN , S.; K RINTZ , C.; B ACON , D. F. Dynamic selection of application-specific


garbage collectors. In: Proceedings of the 4th international symposium on Memory
management (ISMM), ACM, páginas 49–60, 2004.

S TOCKINGER , H. Defining the Grid: A Snapshot on the Current View. In: The
Journal of Supercomputing, Springer Netherlands, páginas 3–17, 2007.

S UN M ICROSYSTEMS , I NC . OpenJDK: The HotSpot Group. Disponível em:


http://openjdk.java.net/groups/hotspot/, acessado 2 de abril, 2010.

T ANENBAUM , A. S. Modern Operating Systems. 3 edição. Prentice Hall, 1104


páginas, 2007.

T CL Tool Command Language (Tcl) Programming Language. Disponível em:


http://www.tcl.tk/, acessado 19 de abril, 2010.

V ICENZI , A. M. R.; W ONG , W. E.; D ELAMARO , M. E.; M ALDONADO , J. C. JaBUTi:


A Coverage Analysis Tool for Java Programs. In: Caderno de Ferramentas do VII
Simpósio Brasileiro de Engenharia de Software (SBES), páginas 79–84, 2003.
REFERÊNCIAS BIBLIOGRÁFICAS 66

VM WARE I NC . VMware ServerTM . Disponível em: http://www.vmware.com/-


products/server/, acessado 5 de maio, 2010.

V OAS , J. Fault Tolerance. Software, IEEE, vol. 18, n. 4, páginas 54–57, 2001.

WAMPLER , D.; P AYNE , A. Programming Scala: Scalability = Functional Programming +


Objects. O’Reilly Media, Inc., 448 páginas, 2009.

W IR TH , N. Recollections about the Development of Pascal. In: The second ACM


SIGPLAN Conference on History of Programming Languages (HOPL), ACM, páginas
333–342, 1993.

W ONG , B.; C ZAJKOWSKI , G.; D AYNÈS , L. Dynamically Loaded Classes as Shared


Libraries: An Approach to Improving Virtual Machine Scalability. International
Symposium on Parallel and Distributed Processing, páginas 38–48, 2003.

W ÜR THINGER , T.; VANTER , M. L. V. D.; S IMON , D. Perspectives of Systems Infor-


matics, Capítulo: Multi-level Virtual Machine Debugging Using the Java Platform
Debugger Architecture, Springer Berlin/Heidelberg, páginas 401–412, 2010.

X IAN , F.; S RISA - AN , W.; J IANG , H. Microphase: An Approach to Proactively Invoking


Garbage Collection for Improved Performance. In: Proceedings of the 22nd annual
ACM SIGPLAN conference on Object-oriented programming, Systems, Languages, and
Applications (OOPSLA), ACM, páginas 77–96, 2007.

X IMIAN MONO: Cross Plataform, Open Source .NET Development Framework. Dis-
ponível em: http://www.mono-project.com/Main_Page, acessado 18 de abril, 2010.

Z HANG , L.; K RINTZ , C. Adaptive Code Unloading for Resource-constrained JVMs. In:
Proceedings of the 2004 ACM SIGPLAN/SIGBED conference on Languages, compilers,
and tools for embedded systems (LCTES), ACM, páginas 155–164, 2004.

Z HANG , L.; K RINTZ , C.; N AGPURKAR , P. Language and virtual machine support for
efficient fine-grained futures in java. In: Proceedings of the 16th International Con-
ference on Parallel Architecture and Compilation Techniques (PACT), IEEE Computer
Society, páginas 130–139, 2007a.

Z HANG , L.; K RINTZ , C.; N AGPURKAR , P. Supporting Exception Handling for Futu-
res in Java. In: Proceedings of the 5th international symposium on Principles and
practice of programming in Java (PPPJ), ACM, páginas 175–184, 2007b.

Você também pode gostar