【JVM】——运行机制(二)

我们继续接着上一篇的内容对JVM的运行机制进行讲解,主要是讲解运行机制的内存模型

【内存结构】


从上图中我们可以看到堆内存的划分如下:


一、刻画了Java程序运行时的堆空间,可以简述成如下2条:

1.JVM中堆空间可以分成三个大区,新生代、老年代、永久代

2.新生代可以划分为三个区,Eden区,两个幸存区

二、参数配置

1.JVM运行时堆的大小

    -Xms堆的最小值

    -Xmx堆空间的最大值

2.新生代堆空间大小调整

     -XX:NewSize新生代的最小值

     -XX:MaxNewSize新生代的最大值

     -XX:NewRatio设置新生代与老年代在堆空间的大小

     -XX:SurvivorRatio新生代中Eden所占区域的大小

3.永久代大小调整

    -XX:MaxPermSize 

4.其他 

     -XX:MaxTenuringThreshold,设置将新生代对象转到老年代时需要经过多少次垃圾回收,但是仍然没有被回收

在上面的配置中,老年代所占空间的大小是由-XX:SurvivorRatio这个参数进行配置的,看完了上面的JVM堆空间分配图,可能会奇怪,为啥新生代空间要划分为三个区Eden及两个Survivor区?有何用意?为什么要这么分?要理解这个问题,就得理解一下JVM的垃圾收集机制(复制算法也叫copy算法)

【内存模型】

1、每一个线程有一个工作内存和主存独立

2、工作内存存放主存中变量的值的拷贝

 

(1)当数据从主内存复制到工作存储时,必须出现两个动作:第一,由主内存执行的读(read)操作;第二,由工作内存执行的相应的load操作;

(2)当数据从工作内存拷贝到主内存时,也出现两个操作:第一个,由工作内存执行的存储(store)操作;第二,由主内存执行的相应的写(write)操作

(3)每一个操作都是原子的,即执行期间不会被中断

 【volatile】

对于普通变量,一个线程中更新的值,不能马上反应在其他变量中,如果需要在其他线程中立即可见,需要使用 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);
    }
}

没有volatile -server 运行 无法停止

volatile 不能代替锁,一般认为volatile 比锁性能好(不绝对)

选择使用volatile的条件是:语义是否满足应用

【可见性】


【有序性】


【指令重排】


【总结】

小编今天的讲解就到这里了

猜你喜欢

转载自blog.csdn.net/tengliu6/article/details/80557403