关于java:JAVA内存区域划分

8次阅读

共计 1459 个字符,预计需要花费 4 分钟才能阅读完成。

依据《JAVA 虚拟机标准》的规定,JAVA 虚拟机在执行 JAVA 程序的过程中会把内存划分为不同的数据区域。不同类型的数据会存储在不同的区域,了解 JAVA 内存区域的工作细节对裂解 JAVA 多线程、线程安全性有着重要意义。

留神,JAVA 内存区域的划分与咱们常说的 java 内存模型 JMM(Java Memery Model) 是两个互不穿插的维度的概念,两者没有任何关系。JMM 次要是将主内存和工作内存的关系、数据从主内存区读取的工作内存、以及从工作内存写回到主内存区、以及不同线程的工作内存间数据同步的问题。

本文次要探讨内存区域的划分,不波及 JMM 相干内容。

从线程隔离角度,能够把这些内存区域分成两局部:线程公有的区域、以及线程共享的区域。 顾名思义,线程公有区域的数据是各线程独享的,因而,存储在线程公有区域的数据不会有线程平安问题。线程共享区域的数据是要在不同线程间共享的,这部分数据才有可能引起线程平安问题。

程序计数器

程序计数器(Programe Counter Register)是属于线程公有区域的数据区。

程序计数器数据区根本是程序员最不须要关怀的区域。

程序计数器是为了管制程序运行、用来记录须要执行的字节码的地址的,为了精确记录多线程环境下每一条线程的执行指令地址,程序计数器数据区必须是线程公有的区域。

办法区

办法区(Method Area)是线程共享的数据区域。

办法区用来存储虚拟机加载的类信息,包含类的元数据、常量、动态变量等。

大家能够反过头来想想,为什么动态变量能够在类的不同实体对象之间共享?也正因为如此,动态变量使用不当的话也很容易引起线程平安问题。

另外,String s=new String(“12345”),那么 s 是否会存储在办法区?s.intern() 呢?

本地办法栈

本地房倒退(Native Method Stack)属于线程公有的数据区。

本地办法栈是为 JAVA 应用到的本地(Native)办法服务的,因为《JAVA 虚拟机标准》没有对本地办法栈做硬性规定,所以,有些虚拟机比方 HotSpot 把本地办法栈和虚拟机栈合二为一了。

虚拟机栈

虚拟机栈(VM Stack)是线程公有的数据区。

虚拟机栈和堆是程序员打交道最多的数据区,也是程序员最须要关怀的内容。

JAVA 虚拟机栈用于存储局部变量,比方 java 办法内定义的变量、办法返回等。每一个 JAVA 办法执行的时候,JAVA 虚拟机都会同步创立一个栈帧(Stack Frame),JAVA 办法的执行过程对应着局部变量的进栈出栈过程。

JAVA 栈保留的是 JAVA 根本类型或对象援用(refrence),保留在虚拟机栈的局部变量表中,以变量槽(slot)来示意。

堆(JAVA Heap)是线程共享的数据区。

JAVA 堆是寄存 JAVA 对象的内存区域,简直所有的 JAVA 对象都存储在 JAVA 堆中。

JAVA 堆也是 JAVA 垃圾回收器(GC)的次要工作对象,不同的垃圾回收器或者垃圾回收算法,会依照不同的形式划分 JAVA 堆,比方新生代、老年代、永恒代 … 等等,不管怎么划分,这样的划分仅仅是为了垃圾回收服务的,并不是 JAVA 堆内存必须依照这样的形式进一步粗疏划分。

存储在线程共享的数据区中的数据,才有可能存在线程安全性问题。 也就是说,办法区、堆内的数据,有可能存在零碎安全性。然而办法区中存储的次要是类的元数据信息以及动态变量,从线程平安角度来看,利用须要重点关注的是动态变量。内存对中存储的是 JAVA 对象,在多线程高并发利用中,是引起线程平安问题的次要数据存储区域、因而,也是程序员最应该关注的中央。

正文完
 0