龙空技术网

请分清楚Java内存区域和Java内存模型

李故老样子 52

前言:

目前姐妹们对“java内存区域和内存模型”大概比较注意,同学们都需要分析一些“java内存区域和内存模型”的相关知识。那么小编同时在网络上网罗了一些对于“java内存区域和内存模型””的相关资讯,希望同学们能喜欢,兄弟们一起来了解一下吧!

java内存区域是java虚拟机在执行java程序的时候会把它所管理的内存进行划分不同的数据区域。

但是java内存模型是为了屏蔽各种硬件和操作系统的内存访问的差异,已实现java程序在不同的操作系统中都能达到一致的访问效果

Java内存区域

线程共享区:

堆:堆可分为eden区和survior to和survior from 区 刚创建的对象,且堆内存够放下这个对象,都会放在eden区。

方法区: 存储已经被加载的类信息,常量,静态变量,即时编译后的代码等数据。在hotspot虚拟机中方法区也被称为老年代。

线程独享区

Java虚拟机栈:在我们代码在运行是调用一个方法就会创建一个栈帧用于存储局部变量表,动态链接,操作数栈,方法出口等。调用方法的过程也就是压栈和弹栈的过程,栈的数据结构是先进后出的我们可以想一下主方法调用其他方法,其他方法调用完成那其他的方法就弹栈了谈完后其以及已经将动态链接的数据已经改变,于是你的主方法内的数据也随即改变。仔细品品。

本地方发栈: 本地方法栈和Java虚拟机栈的作用类似,Java虚拟机栈是为java方法的使用而执行的,但是本地方法栈是为了Java虚拟机调用的native方法执行的。正是因为本地方法栈不会限制使用的语言,使用的方法还有数据结构。

程序计数器:粗糙一点也就是为了记录代码执行到那一块了。还有就是我们在执行多线程的时候,在虚拟机中并不是所谓的同步执行的,而是通过线程的切换并分配处理器的时间的方式来实现的,所以在切换的过程中有的线程执行了一半,又切换到了其他线程那就得将其字节码指令执行到那一块就得记录下来,这也是程序计数器为什么是私有的原因。

直接内存(非Java虚拟机中运行时动态区域,但是也会引起OOM) image.png

直接内存并不属于JVM动态运行时区域,我们在使用NIO的时候基于通道与缓冲区的方式(buffer)的I/O的方式,他可以使用native函数库直接分配堆外内存 ,然后通过存储在Java堆种的dirctyByteBuffer对象作为这块堆内存的一面用进行操作。

java内存模型

Java的内存模型重要的目标是定义程序中的各个变量的访问规则。即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处变量只是针对全局变量和静态字段,和构成数组的对象元素。

Java的内存模型分为 主内存,工作内存。

工作内存:每一个线程都拥有自己的工作内存,工作内存保存的是从主内存复制拷贝过来的副本,不同的线程之间是不可以直接进行工作内存的访问,必须通过主内存作为中间人才可以访问。

主内存:主内存就用来存放所有的公共变量。线程间可以共享的变量。

Java内存模型和Java运行时动态内存模型类比的话,那么主内存就是其Java堆中的那些对象实例,而工作内存区域就是Java虚拟机栈中的局部变量表还有refrence所指向的数据,还有方法参数等。 image.png

思考一下

volatile关键字是如何达到变量在各个线程间是可见的呢?

标签: #java内存区域和内存模型