类的生命周期以及JMM(Java Memory Model)

 

 

 

 

 

类的生命周期:类的加载->连接(验证,准备,解析)->初始化->使用->类的卸载

1.类的加载

  查找并加载类的二进制数据(class文件)
  硬盘上的class文件加载到jvm内存中

2.连接 :验证,准备,解析

             

   

jvm结束生命周期的时机:

  • 正常结束
  • 异常结束/错误
  • System.exit()
  • 操作系统异常

 

 

 

JVM的内存模型(JAVA Memory Model  JMM)

JVM将内存分为两个部分主内存区和工作内存区

 

注意:

1.各个线程只能访问自己私有的工作内存(不能访问其它线程的工作内存,也不能访问主内存)
2.不同线程之间,可以通过主内存间接的访问其它线程的工作内存。

 

 

 

 

 

 

 

 Volatile:

重排序就是把复合动作变成几个原子动作,再对原子动作进行二次排序

比如: int b = 10 ==> int b;b=10两步操作

 

 

 单例模式(双重检测加锁式)举例:

 

 

 

 

 

 

 

    //volatile 是不能保证原子性和线程安全的
    static volatile int  num = 0;
    public static void main(String[] args) throws InterruptedException {    
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                for(int j = 0;j<3000;j++) {
                    num++;
                }
            }).start();
        }
        
        Thread.sleep(2000);//为了保证下面输出的num 的正确性,因为子线程可能还没跑完
        System.out.println(num); //最终的值达不到300000    因为 num++是一个非原子操作

    }

使用 java.util.concurrent.atomic  下的 AtomicInteger 

package JUC.Atomic;

import java.util.concurrent.atomic.AtomicInteger;

public class TestAtomic {

    //volatile 是不能保证原子性和线程安全的
    //static volatile int  num = 0;
    static AtomicInteger atomicInt = new AtomicInteger(0);
    public static void main(String[] args) throws InterruptedException {    
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                for(int j = 0;j<3000;j++) {
                    atomicInt.incrementAndGet();
                }
            }).start();
        }
        
        Thread.sleep(2000);//为了保证下面输出的num 的正确性,因为子线程可能还没跑完
        System.out.println(atomicInt); 

    }

}

JVM运行时的内存区域

 

 

程序计数器:

 

 

 

 

 

 

 

堆:

 

 

 

 

 

 

 

 

 

 

 

 

 

方法区

 

 

 

 

 

 

 

 常量池:存放编译期间产生的字面量("abc")、符号引用

 

posted @ 2020-12-04 17:39  Joyce502  阅读(75)  评论(0)    收藏  举报