JVM内存模型详解

168 阅读4分钟

小知识,大挑战!本文正在参与“  程序员必备小知识  ”创作活动

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

为什么要学JVM相关知识

又是我,我又去充了三毛钱电费! 在这里插入图片描述

追根溯源

入了Java语言这门,你就逃不了JVM这一块了。

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。——摘自百度百科

平时我们就只是编写代码,然后编译运行看结果就行了,并没有去了解整个程序是如何在计算机上运行的,随着我们的学习,我们已经不在满足只是完成程序的实现,我们跟开始注意程序运行的高效性,这个时候我们就要去了解JVM,好对程序进行相应的调优。 在这里插入图片描述

JVM内存模型

既然是模型,必然图的表现是最为直观的,分区解读吧。 jneiava7和java8的nei

线程私有区

线程私有的包括虚拟机栈,本地方法栈和程序计数器。

程序计数器

程序计数器在jvm的内存中占非常小的一块,几乎可以忽略不计,可以当成是当前线程字节码的行号指示器,别看它小,但是功能可不简单,线程的跳转,循环,分支,异常处理,线程恢复等基础功能都要依赖程序计数器去完成,当程序计数器执行Native方法时,这是计数器就是空的,同时程序计数器也是jvm规范中唯一没有规定OutOfMemoryError情况的区域。

虚拟机栈

虚拟机栈算是私有部分中最重要的一块区域了,他的生命周期伴随着线程,随线程而生,随线程而灭。 线程中的每个方法在创建的时候都会在虚拟机栈中创建一个栈帧,里面包含着局部变量,操作栈,动态连接和方法的返回地址每个方法的执行到结束对应着一个栈帧在虚拟机栈从入栈到出栈的过程 当线程请求的栈的深度大于虚拟机所允许的深度,就会抛出StackOverflowError。虚拟机是可以动态扩展内存的,当扩展的内存超过jvm规定的内存,就会报OutOfMemoryError。 在这里插入图片描述

本地方法栈

本低方法栈和虚拟机栈,主要为虚拟机使用到的Native方法服务,就因为很像,有的虚拟机直接就把本地方法栈和虚拟机栈合二为一,比如Sun HotSpot虚拟机,本地方法栈也会抛出StackOverflowError和OutOfMemoryError。

线程共享区

线程共享区包括方法区和堆。

方法区

方法区作为所有线程共享的一块区域,存放着已经被虚拟机加载的类信息,静态变量,静态方法,常量和成员方法等。 运行时常量池是方法区的一部分,class文件除了有类的字段、接口、方法等描述信息之外,还有常量池用于存放编译期间生成的各种字面量和符号引用。 1.7版本之前,因为方法区没有要求强制进行垃圾回收,所以方法区也叫永久代。(HotSpot虚拟机以永久代来实现方法区,从而JVM的垃圾收集器可以像管理堆区一样管理这部分区域,从而不需要专门为这部分设计垃圾回收机制。)1.7版本之后,永久代就被移除了,用元空间取代了永久代,元空间并不在jvm的内存中,而是在本地内存中。

在这里插入图片描述

堆算是jvm内存中占比最大的区域了,也是最复杂的一个区域,但却只有一个功能,存放对象实例,那为什么说复杂呢,因为根据垃圾回收的算法,划分了多个空间。 根据垃圾回收算法可以分两个大的区域,年轻代和老年代, 老年代占2/3的堆空间 年轻代栈1/3的空间 其中年轻代又分为 Eden区,From Survivor区,To Survivor区,比例是8:1:1。

在这里插入图片描述 对应的垃圾回收算法我会单写一个,等我吧。

最后给你们推荐一本书吧

在这里插入图片描述

这里面基本都是我自己的理解,如果有错误请写在下面,跟我打一架! 在这里插入图片描述 古德拜~