浅析java内存模型(JMM)

浅析java内存模型(JMM)

内存模型逻辑图

JDK1.7内存模型
在这里插入图片描述
这里就拿JDK1.7的内存模型说明内存模型运行时数据区中各部分的作用

程序计数器

程序计数器是一个记录着当前线程所执行的字节码的行号指示器。
JVM的多线程是通过CPU时间片轮转(即线程轮流切换并分配处理器执行时间)算法来实现的。在JVM中,通过程序计数器来记录某个线程的字节码执行位置。因此,程序计数器是具备线程隔离的特性,也就是说,每个线程工作时都有属于自己的独立计数器。
程序计数器占用内存很小,在进行JVM内存计算时,可以忽略不计。程序计数器,是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError的区域

虚拟机栈

在这里插入图片描述

本地方法栈

本地方法栈和Java栈所发挥的作用非常相似,区别不过是Java栈为JVM执行Java方法服务,而本地方法栈为JVM执行Native方法服务。本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。

heap(堆)

虚拟机堆:堆是JVM所管理的内存中国最大的一块,是被所有Java线程锁共享的,不是线程安全的,在JVM启动时创建。堆是存储Java对象的地方,这一点Java虚拟机规范中描述是:所有的对象实例以及数组都要在堆上分配。Java堆是GC管理的主要区域,从内存回收的角度来看,由于现在GC基本都采用分代收集算法,所以Java堆还可以细分为:新生代和老年代;新生代再细致一点有Eden空间、From Survivor空间、To Survivor空间等。

方法区

  1. 方法区存放了要加载的类的信息(名称、修饰符等)、类中的静态常量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当在程序中通过Class对象的getName.isInterface等方法来获取信息时,这些数据都来源于方法区。
  2. 方法区是被Java线程所共享的,不像Java堆中其他部分一样会频繁被GC回收,它存储的信息相对比较稳定,在一定条件下会被GC,当方法区要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。方法区也是堆中的一部分,就是我们通常所说的Java堆中的永久区 Permanet Generation,大小可以通过参数来设置,可以通过-XX:PermSize指定初始值,-XX:MaxPermSize指定最大值。
  3. 方法区包含 常量池Constant Pool
    常量池本身是方法区中的一个数据结构。常量池中存储了如字符串、final变量值、类名和方法名常量。常量池在编译期间就被确定,并保存在已编译的.class文件中。一般分为两类:字面量和应用量。字面量就是字符串、final变量等。类名和方法名属于应用量。应用量最常见的是在调用方法的时候,根据方法名找到方法的应用,并以此定为到函数体进行函数代码的执行。应用量包含:类和接口的权限定名、字段的名称和描述符,方法的名称和描述符。

生命周期

跟线程相同

程序计数器、栈、本地方法栈都是线程创建时创建、销毁时销毁的。线程独享,线程安全的。

所有线程共享

方法区、堆

猜你喜欢

转载自blog.csdn.net/lanwp5302/article/details/86543961