JVM的并发问题

Java内存模型

1.程序,进程,线程的基本概念?

  1.程序:是指完成某一项任务的代码序列(静态的概念)

  2.进程:程序在某些数据上的一次运行(动态概念)

  3.线程:一个进程可能包含一个或者多个线程(占有资源的独立单元)

2.JVM的内存区域?

      

         JVM内存模型                                                                                VMstack

  1.方法区:主要存储类信息(通过classLoader:类加载器加载进来的),常量信息,使用static关键字修饰的属性,方法,代码块 等。当使用反射原理进行类加载时其实就是调用的方法区的数据。(信息共享)在JDK1.6版本中,常量池(这里特指运行时常量池,我们一般说的常量池也都是指的运行时常量池)是存放于方法区中的(因此方法区可能会经常内存溢出),JDK1.7的时候常量池移到了JAVA堆(Heap)中,在JDK1.8的时候,已经没有方法区了,取而代之的是一块叫元数据(metaSpace)的空间.

  2.Java堆区:主要存放实例对象,当使用new关键字创建一个对象的时候,就会把相关信息放在堆区域,所以这也是GC活动的主要区域,同时也是发生OOM(内存溢出)的主要区域。(信息共享)几乎所有的对象分配内存都是在java堆中进行,但不是说所有对象100%都在java堆中分配内存,是因为有两种例外情况不会在java堆中分配内存,第一种是TLAB(线程本机分配缓存),另一种是栈上分配.

  3.VMstack(虚拟机栈):Java方法运行的内存模型,在VMstack中,每一个方法都有唯一的一个栈帧与之对应,存放这个方法的一些私有信息,比如:局部变量,引用类型数据的地址,操作数栈等...。因为是存储一个方法的信息,所有不能实现数据共享,是私有的。java方法执行的内存模型,每个方法在执行的时候会封装成一个栈帧,存放[局部变量表/操作数栈/动态链表/方法出口]等信息,方法的执行对应栈帧入栈和出栈的过程.栈的深度是有大小的,默认情况下栈的内存为1M,因此虚拟机栈除了发生内存溢出异常,还有可能发生StackOverFlowError异常.

  4.PC(程序计数器):是Java的私有数据,这个数据就是执行下一条指令的地址。(私有的)当前线程执行的字节码行号指示器,是JVM中唯一一块没有内存溢出异常的区域.

  5.Native method stack(本地方法栈):与JVM的native。(私有的)和虚拟机栈作用类似,区别在于本地方法栈保存的是native方法的信息.

3.Java内存模型(JMM:Java memory model)?

  Java内存模型,是一种规范,是抽象的模型概念。

    1)主内存:共享的数据信息

    2)工作内存:私有信息,如果是基本数据类型那么直接分配到工作内存。如果是引用数据类型,那么引用的地址存放在工作内存,引用的对象仍然存放在堆中。

    一个线程访问主内存数据的工作方式当一个线程想要访问主内存中的数据的时候,首先会访问自己的工作空间(工作空间是创建线程的时候同步创建这个线程的私有工作空间),如果工作空间有想要的数据,那么就会把数据返回,如果工作空间没有线程想要的数据,那么工作空间就会去主内存中找数据。如果找到了,那么工作空间就会把内存中的数据复制到工作空间,这样线程就可以访问和修改工作空间里的数据了,等修改完了,工作空间再把数据返回给主内存。

 物理机的CPU处理缓存不一致问题方法?

  1.总线加锁,缺点:降低CPU的吞吐量

  2.缓存上的一致性协议(MESI):当CPU在cache中操作数据时,如果该数据时共享变量,那么数据在cache读到寄存器中,然后进行修改,同时将数据的标识符(cache line)置为无效,这样其他的CPU就会从内存中去读取数据,而不是读自己的缓存中的数据了。

 并发编程的三个重要特性?

  1.原子性:不可分割

  2.可见性:线程只能操作自己工作空间里的数据。

  3.有序性:程序中的顺序不一定是CPU的执行顺序,通过编译重排序和指令重排序来提高效率。

原文地址:https://www.cnblogs.com/wk-missQ1/p/12367100.html