java内存模型

谈到Java内存模型,指的就是运行时数据区,按照线程是否共享可按图示划分

image

1.程序计数器:可以看作当前线程所执行的字节码的行号指示器,它是逻辑计数器,不是物理的,通过改变计数器的值来选取下一条要执行的指令,每个线程有独立的计数器,只为java方法计数,不发生内存泄漏

2.虚拟机栈:描述的是java方法执行时的线程模型,包含了单个线程每个方法执行的栈帧,栈帧存储了局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法被调用直至执行完毕的过程,对应着一个栈帧在虚拟机栈中从入栈到出栈的过程

①局部变量表:包含方法执行过程中的所有变量
②操作数栈:负责入栈、出栈等操作

该内存规定了两种异常:递归引发的StackOverflowError(递归过深,栈桢数超过虚拟栈深度)和虚拟机栈过多引发的OutOfMemoryError(当虚拟机栈可以动态扩展时,如果无法申请足够多的内存,就会抛出异常)

3.本地方法栈:与虚拟机栈发挥的作用是相似的,区别只是虚拟机栈为虚拟机执行java方法服务,本地方法栈为Native(本地方法)服务

4.Java堆: Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,逻辑上连续,物理上可不连续,既可以被实现成固定大小的,也可以设置成可扩展的。当类加载器读取了类文件后,需要把类、方法、常量、变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行。

常量池:存放编译器生成的字面量和符号引用量

JVM三大性能调优参数-Xms -Xmx -Xss

image

在调用java指令执行程序时,通过传入以上三个参数分别调整java堆以及线程所占内存的大小

5.元空间:存储的是运行环境必须的类信息,取代永久代,不在Java虚拟机的堆中实现,而是使用本机物理内存实现。






补充:在Java8中,永久代已经被移除,被一个称为元空间的区域所取代。元空间的本质和永久代类似。
元空间与永久代之间最大的区别在于:永久代使用的JVM的堆内存(但是逻辑上是非堆的),但是java8以后的元空间并不在虚拟机中而是使用本机物理内存(所以在上图中,我用虚线表示)。
永久代:是一个常驻内存的区域,用于存放JDK自身所携带的Class,Interface的元数据,即存储的是运行环境必须的类信息,被转载进此区域的数据是不会被垃圾回收的,只有关闭JVM才会释放此区域所占用的内存空间。
元空间:取代永久代,不在Java虚拟机的堆中实现,而是使用本机物理内存实现。默认情况下元空间大小仅受本地内存限制。类的元数据放入native memory,字符串常量在Java堆中(运行时常量和基本类型常量在元空间——方法区)
PS:jdk1.8,jvm把字符串常量池移到了堆内存里。此时方法区=元空间

方法区(Method Area)并不是所谓的存储方法的区域,而是供各线程共享的运行时内存区域。它存储了已被虚拟机加载的类信息、方法信息、字段信息、常量(被final修饰)、静态变量、即时编译器编译后的代码缓存等。

方法区也是一种规范,在不同虚拟机里头实现是不一样的,最典型的实现就是HotSpot虚拟机Java8之前的永久代(PermGen space)和Java8的元空间(Metaspace)。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容