Baixe o app para aproveitar ainda mais
Prévia do material em texto
IF688 – Ambiente de Execução e Geração de Código Estado de um programa Execução de um programa é resultado de uma sequência de transições de estado S1 S2 ... Sn Estado Inicial Estado Final Componentes Área estática: espaço para meta-dados associados ao código Heap: espaço reservado para alocação dinâmica de memória Program Counter (PC): instrução corrente Pilha: Contexto de chamada de funções Componentes Área estática: espaço para meta-dados associados ao código Heap: espaço reservado para alocação dinâmica de memória Program Counter (PC): instrução corrente Pilha: Contexto de chamada de funções Um PC e Pilha para cada thread do programa! Área estática Representação do código Instruções (e.g., métodos) Estrutura de dados Exemplo public class Foo { public static void main(String[] args){ int t = 10; t += t + 1; } } $ javac Foo.java $ javap -classpath . -c Foo Exemplo $ javac Foo.java $ javap -classpath . -c Foo class Foo extends java.lang.Object{ Foo(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } É preciso saber que código será executado e identificar variáveis globais do programa! Java bytecodes Total de 204 instruções Próximo de 100 quando consideramos apenas uma por grupo (iadd, dadd, etc.) Veja: http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html Pilha Fluxo de controle de chamadas de funções Cada frame da pilha corresponde ao registro de ativação de uma função. Criada pelo chamador da função Pilha Em C, armazena apenas os registros de ativação das chamadas de funções Em Java, a pilha também é usada na interpretação de instruções Exemplo $ javac Foo.java $ javap -classpath . -c Foo class Foo extends java.lang.Object{ Foo(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } Exemplo para um procedimento public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } 10 ? Reservado para variáveis locais Exemplo para um procedimento public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } 10 Reservado para variáveis locais Exemplo para um procedimento public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } 10 10 Reservado para variáveis locais 10 Exemplo para um procedimento public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } 10 10 Reservado para variáveis locais 10 1 Exemplo para um procedimento public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } 10 10 Reservado para variáveis locais 11 Exemplo para um procedimento public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } 21 10 Reservado para variáveis locais Exemplo para um procedimento public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } 21 Reservado para variáveis locais Exemplo para um procedimento public static void main(); Code: 0: bipush 10 2: istore_0 3: iload_0 4: iload_0 5: iconst_1 6: iadd 7: iadd 8: istore_0 9: return } 21 Retorna ao chamador O registro de ativação contém endereço para onde o controle deve retornar. Isto é, próximo PC. Exemplo para vários procedimentos public class Foo { public static void main(String[] args){ bar(10); } static void bar(int t){ t += t + 1; } } Exemplo para vários procedimentos public class Foo { public static void main(String[] args){ bar(10); } static void bar(int t){ t += t + 1; } } main 10 Exemplo para vários procedimentos public class Foo { public static void main(String[] args){ bar(10); } static void bar(int t){ t += t + 1; } } main bar 10 main 10 Exemplo para vários procedimentos public class Foo { public static void main(String[] args){ bar(10); } static void bar(int t){ t += t + 1; } } main bar 10 main 10 ... bar main 10 10 Exemplo para vários procedimentos public class Foo { public static void main(String[] args){ bar(10); } static void bar(int t){ t += t + 1; } } main bar 10 main 10 ... bar main 10 10 Referência para variáveis locais e parâmetros do procedimento. Heap Grafo Nós correspondem as alocações dinâmica de dados Aresta correspondem a referências para tais dados a partir de dados alocados dinâmicamente Referências podem partir da pilha ou da área estática também Exemplo public class Tree { Node root; static class Node { Node l, r; int val; Node(int v) { val = v; }... } Tree(int v) { if (root == null) root = new Node(v); else ... } ... } Exemplo public class Tree { ... public static void main(String[] args){ Tree t = new Tree(5); } } root val=5, l= null , r=null Objetos estão na heap! Instâncias não alcançáveis a partir da pilha ou campos estáticos estão sujeitas a garbage collection! 27 Memory Leaks O programador pode esquecer de liberar espaço de memória Em C(++), usa-se explicitamente comando (delete) para liberar objetos alcançáveis por uma determinada referência Em Java, o programador precisa liberar referência para objetos Memory Leaks: Exemplo Heap p Neste cenário, objeto referenciado por p não é mais usado. Porém, o programador esqueceu de liberar o objeto aponta por p! Memory Leaks: Exemplo Heap p Heap p null Este cenário mostra o objeto sendo liberado. Os nós em cor escura estão disponíveis para coleta. Garbage collection (Mark-Sweep) Heap Garbage collection (Mark-Sweep) Heap Garbage collection (Mark-Sweep) Heap Garbage collection (Mark-Sweep) Heap Heap e Pilha public class Tree { ... public static void main(String[] args){ Tree t = new Tree(5); } } $ javap -classpath . -c Tree public class Tree extends java.lang.Object{ public static void main(java.lang.String[]); Code: 0: new #2; //class Tree 3: dup 4: iconst_5 5: invokespecial #3; //Method "<init>":(I)V 8: astore_1 9: return }} Heap e Pilha root=null $ javap -classpath . -c Tree public class Tree extends java.lang.Object{ public static void main(java.lang.String[]); Code: 0: new #2; //class Tree 3: dup 4: iconst_5 5: invokespecial #3; //Method "<init>":(I)V 8: astore_1 9: return }} ? ? Heap e Pilha root=null $ javap -classpath . -c Tree public class Tree extends java.lang.Object{ public static void main(java.lang.String[]); Code: 0: new #2; //class Tree 3: dup 4: iconst_5 5: invokespecial #3; //Method "<init>":(I)V 8: astore_1 9: return }} ? ? Heap e Pilha root=null $ javap-classpath . -c Tree public class Tree extends java.lang.Object{ public static void main(java.lang.String[]); Code: 0: new #2; //class Tree 3: dup 4: iconst_5 5: invokespecial #3; //Method "<init>":(I)V 8: astore_1 9: return }} ? 5 ? Heap e Pilha root val=10, l= null , r=null $ javap -classpath . -c Tree public class Tree extends java.lang.Object{ public static void main(java.lang.String[]); Code: 0: new #2; //class Tree 3: dup 4: iconst_5 5: invokespecial #3; //Method "<init>":(I)V 8: astore_1 9: return }} ? ? Heap e Pilha root val=10, l= null , r=null $ javap -classpath . -c Tree public class Tree extends java.lang.Object{ public static void main(java.lang.String[]); Code: 0: new #2; //class Tree 3: dup 4: iconst_5 5: invokespecial #3; //Method "<init>":(I)V 8: astore_1 9: return }} ? Heap e Área Estática ...ou dados e código Como organizar os dados ? Como implementar dynamic binding ? Exemplo class Point { protected int x,y; public Point (int x, int y) { this.x=x; this.y=y; } public void move(int dx, int dy) { this.x += dx; this.y += dy; } public float area() { return 0.0; } public float dist(Point that) { int dx= this.x – that.x; int dy= this.y – that.y; return Math.sqrt(dx*dx + dy*dy); } } Exemplo 1: código init move area dist x y x y x y Instâncias Heap Área Estática Exemplo 2: atualização de estado Construtor move area dist Heap Point p = new Point(2,3); Point q = new Point(0,0); p q 0 0 2 3 Área Estática Pilha Exemplo 2: atualização de estado Construtor move area dist Heap Point p = new Point(2,3); Point q = new Point(0,0); p q 0 0 3 4 p.move(1,1); Área Estática Pilha Exemplo 2: atualização de estado Construtor move area dist Heap Point p = new Point(2,3); Point q = new Point(0,0); p q 0 0 3 4 p.move(1,1); q = p; Área Estática Pilha Dynamic binding class Circle extends Point { protected int r; public Circle (int x, int y, int r) { this.x = x; this.y = y; this.r = r; } public int radius() { return this.r; } public double area() { double pi=3.1416; return pi*this.r*this.r; } } class Box extends Point { protected int w,d; public Box (int x, int y, int w, int d) { this.x = x; this.y = y; this.d=d; this.w = w; } public int width() { return this.w; } public int depth() { return this.d; } public double area() { return (double) this.w * this.d; } } Criação de objetos e herança Construtor move(herdado) area(sobreposto) dist(herdado) radius Construtor move(herdado) dist(herdado) area(sobreposto) width depth Heap 0 12 4 0 4 8 8 p c b Área Estática Pilha Point p = null; Circle c = new Circle(0,12,4); Box b = new Box(0,4,8,8); Polimorfismo Construtor move(herdado) area(sobreposto) dist(herdado) radius Construtor move(herdado) dist(herdado) area(sobreposto) width depth 20 32 4 0 4 8 8 p c b a 50.3 p = c; p.move(20,20); double a = p.area(); Área Estática Pilha Heap Geração de código Assembler é usado para isolar programador de detalhes de implementação Exemplos: jasmin, ilasm Vamos usar MS ilasm.exe Entrada: MSIL (Microsoft Intermediate Language) Saída: código nativo Exemplo: Entrada de ilasm (1/3) // Metadata version: v2.0.50215 .assembly extern mscorlib { .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 2:0:0:0 } .assembly sample { .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) .hash algorithm 0x00008004 .ver 0:0:0:0 } .module sample.exe // MVID: {A224F460-A049-4A03-9E71-80A36DBBBCD3} .imagebase 0x00400000 // .......................SEE NEXT SLIDE Exemplo: Entrada de ilasm (2/3) // SEE PREVIOUS SLIDE .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY // Image base: 0x02F20000 // =============== CLASS MEMBERS DECLARATION =================== .class public auto ansi beforefieldinit Hello extends [mscorlib]System.Object { .method public hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 13 (0xd) .maxstack 8 IL_0000: nop IL_0001: ldstr "Hello World!" IL_0006: call void [mscorlib]System.Console::WriteLine(string) IL_000b: nop IL_000c: ret } // ....................... SEE NEXT SLIDE Exemplo: Entrada de ilasm (3/3) // SEE PREVIOUS SLIDE .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method Hello::.ctor } // end of class Hello Detalhes de MSIL e uso do ilasm em aula de laboratório.
Compartilhar