Android 架构/模式笔试&&面试经验

jvm运行机制

2017-07-09  本文已影响31人  Loofer

当代码写的多了,有时容易产生疑惑,这段代码容不容易产生内存溢出呢?该怎么写才更为面向对象利于后期扩展,充分解耦。需要解决这些疑惑就需要对jvm虚拟机有一定的了解了。对jvm的了解也更能帮助我们迈向更为高级的层次。
先来看看jvm的运行机制吧。

JVM启动流程

jvm启动流程图

JVM基本结构

JVM基本结构 java堆分区

java堆分为新生代老年代两个分区,新生代又分为eden区、s0(又称from区)、s1(又称to区)。

存放局部变量表包含参数和局部变量

看个例子:


public class StackDemo {
    public static int runStatic(int i,long l,float  f,Object o ,byte b){
        return 0;
    }

    public int runInstance(char c,short s,boolean b){
        return 0;
    }
}

上述代码在栈空间的内存图如下:

栈内存示例
函数调用组成帧栈
public static int runStatic(int i,long l,float  f,Object o ,byte b){
    return runStatic(i,l,f,o,b);
}
函数调用栈空间图
操作数栈

Java没有寄存器,所有参数传递使用操作数栈
示例代码

public static int add(int a,int b){
    int c=0;
    c=a+b;
    return c;
}

运行顺序

0: iconst_0 // 0压栈
1: istore_2 // 弹出int,存放于局部变量2
2: iload_0 // 把局部变量0压栈

3: iload_1 // 局部变量1压栈
4: iadd //弹出2个变量,求和,结果压栈
5: istore_2 //弹出结果,放于局部变量2
6: iload_2 //局部变量2压栈
7: ireturn //返回

内存执行图
栈上分配

C++ 代码示例

C++ 代码示例 图片.png
栈、堆、方法区交互

示例代码:

public class AppMain {   
    //运行时, jvm 把appmain的信息都放入方法区  
    public   static   void  main(String[] args)  {
        //main 方法本身放入方法区。  
        Sample test1 = new  Sample( " 测试1 " );  
        //test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面
        Sample test2 = new  Sample( " 测试2 " ); 
        test1.printName();
        test2.printName(); 
    }
} 
public class  Sample {
    //运行时, jvm 把appmain的信息都放入方法区  
    private  name;     
    
    //new Sample实例后, name 引用放入栈区里,  name 对象放入堆里 
    public  Sample(String name) { 
        this .name = name; 
    } 
    
    //print方法本身放入 方法区里。
    public   void  printName(){ 
        System.out.println(name); 
    }
}

内存模型

  • 当数据从主内存复制到工作存储时,必须出现两个动作:第一,由主内存执行的读(read)操作;第二,由工作内存执行的相应的load操作;当数据从工作内存拷贝到主内存时,也出现两个操作:第一个,由工作内存执行的存储(store)操作;第二,由主内存执行的相应的写(write)操作
volatile
public class VolatileStopThread extends Thread{
    private volatile boolean stop = false;
    public void stopMe(){
        stop=true;
    }

    public void run(){
        int i=0;
        while(!stop){
            i++;
        }
       System.out.println("Stop thread");
    }

    public static void main(String args[]) throws InterruptedException{
        VolatileStopThread t=new VolatileStopThread();
        t.start();
        Thread.sleep(1000);
        t.stopMe();
        Thread.sleep(1000);
    }
}
可见性
有序性
指令重排
坏线程间的有序性
保证有序性的方法
指令重排的基本原则

编译和解释运行的概念

上一篇 下一篇

猜你喜欢

热点阅读