JVM是什么呢?

JVM(Java Virtual Machine,Java虚拟机)

Java程序的跨平台特性主要是指字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上运行,Java虚拟机中的Java解释器负责将字节码文件解释成为特定的机器码进行运行。因此在运行时,Java源程序需要通过编译器编译成为.class文件。众所周知java.exe是java class文件的执行程序,但实际上java.exe程序只是一个执行的外壳,它会装载jvm.dll(windows下,下皆以windows平台为例,linux下和solaris下其实类似,为:libjvm.so),这个动态连接库才是java虚拟机的实际操作处理所在。

JVM是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。所以,JAVA虚拟机JVM是属于JRE的,而现在我们安装JDK时也附带安装了JRE(当然也可以单独安装JRE)。

  • JVM内存结构

1、JVM内存结构主要由三部分组成,分别是堆、方法区、栈

  1. 堆:内存占用最大,包括新生代(new space)和老年代(old space),新生代包含伊甸园(Eden)区、From Survivor空间、To Survivor空间.默认情况下按照8:1:1的比例进行分配.
  2. 堆是Java虚拟机所管理的内存中最大的一块存储区域,堆内存被所有线程共享.主要存放使用new关键字创建的对象.所有对象实例以及数组都要再对上分配.垃圾收集器就是根据GC算法,收集堆上对象所占用的内存空间(收集的是对象占用的空间,而不是对象本身). 堆中对象都需要考虑线程安全的问题,有垃圾回收机制
  3. 新生代存储“新生对象”,我们新创建的对象存储再年轻代中,当年轻代中内存不足以放下新对象时,则会触发Minor GC,清理年轻代内存空间.
  4. 老年代存储长期存活的对象和大对象,年轻代中存储的对象,经过多次GC后仍然存活的对象会移动到老年代中进行存储,老年代空间不足以存放新晋升的对象时,则会触发Full GC,Full GC是清理整个堆空间,包括年轻代和老年代,如果Full GC后,堆中仍无法储存对象,则会抛出OutOfMemory内存溢出异常.
  5. 至于幸存区的两个空间,在垃圾回收阶段解释其作用.

2、方法区:

    注意:在JDK1.8以前,静态成员储存在方法区(永久代)中,此时方法区的实现叫做永久代,在JDK1.8以后,永久代被移除,此时方法区的实现更改为元空间,但由于元空间主要用于存储字节码文件,因此静态成员的存储位置从方法区更改到了堆内存中.在JDK1.6及以前,常量池存储在方法区(永久代)中,在JDK1.7中,方法区被整合到堆内存中,常量池存储在堆内存中,在JDK1.8后,方法区从堆内存中独立出来,常量池存储在方法区(永久代)中.

    1、方法区同Java堆一样是被所有线程共享的区间,用于存储已被虚拟机加载的类信息、常量、静态变量(JDK1.8以前)、即时编译器编译后的代码(即使编译器在类加载器阶段解释),更具体的说,静态变量+常量+类信息(版本、方法、字段等)+运行时常量池存在方法区中,常量池也是方法区的一部分.

2、常量池中存储编译器生成的各种字面量和符号引用.字面量就是java中常量的意思,比如文本字符串,final修饰的常量等.方法引用则包括类和接口的权限定名、方法名和描述符,字段名和描述符等.常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息.

运行时常量池:常量池是*.class文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址JDK1.8将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池,会把串池中的对象返回,JDK1.6将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池,会把串池中的对象返回. StringTable也存在垃圾回收,如果想提高其性能,可以将其内部的桶buffer数提高,并且使用intern()方法可以避免重复字符串过多造成内存滥用.

比如下面这段代码:

S3==s5的返回值为true,因为在执行s3=“ab”时,就会在常量池中查询”ab”字符串,有则直接将“ab”字符串的引用赋值给s3,无则在常量池中储存“ab”字符串,再将引用返回并赋值给s3,当执行s5=“a”+”b”时,在编译阶段就已经优化为“ab”了,所以在常量池中查询”ab”字符串,发现已经存在,则将其引用赋值给s5,所以s5与s3的引用地址相同,则==运算自然为true,但s4!=s3,s4!=s5,因为s4是s1+s2,变量并不能在编译器进行优化,所以会使用StringBuilder().append()进行拼接,并返回新的字符串对象,所以虽然s4、s3、s5内容相同但引用地址不同.所以s4!=s3,s4!=s5

常量池中的字符串仅是符号,第一次用到时才变为对象,利用串池的机制,来避免重复创建字符串对象 字符串变量拼接的原理是stringBuilder ,字符串常量拼接的原理是编译期优化,可以使用intern方法,主动将串池中还没有的字符串对象放入串池

小练习:

输出为false,true,可以自己试试.

再试一试下面这段代码,加深理解:

False,true,true,   x1==x2的结果:   true,如果调换位置,则为false,不调换位置,jdk1.6的话则为false.

3、常量池作用:常量池避免了频繁的创建和销毁对象而影响系统性能,其实现了对象的共享.

3、栈:

1、JVM中的栈包括java虚拟机栈和本地方法栈,两者的区别就是,java虚拟机栈为JVM执行java方法服务,本地方法则为JVM使用到的Native方法服务.两者作用是及其相似的,以下java虚拟机栈简称为栈.

2、定义:限定仅在表头进行插入和删除操作的线性表.即压栈和弹栈都是堆栈顶元素进行操作的,所以栈是先进后出的.栈是线程私有的,它的生命周期与线程相同,每个线程都会被分配一个栈的空间,因此每个线程都具有它私有的一个栈空间,如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常,如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常.

3、栈帧,栈帧是栈的元素(是用于支持虚拟机进行方法调用和方法执行的数据结构),每个线程在调用某个方法,比如方法A(),当线程调用A时,jvm就会在该线程的栈中创建一个栈帧,栈帧中存储了局部变量表、操作数栈、动态连接和方法出口等信息.每个方法从调用到运行结束的过程,就对应着一个栈帧在栈中压栈到出栈的过程.

4、栈帧中,由一个局部变量表存储数据。

局部变量表中存储了基本数据类型(boolean、byte、char、short、int、float、long、double)的局部变量〈包括参数)、和对象的引用(String、数组、对象等),但是不存储对象的内容。局部变量表所需的内存空间在编译期间完成分配,在方法运行期间不会改变局部变量表的大小。局部变量的容量以变量槽(Variable Slot)为最小单位,每个变量槽最大存储32位的数据类型。对于64位的数据类型(Iong、double),JVM会为其分配两个连续的变量槽来存储。以下简称Slot 。JVM通过索引定位的方式使用局部变量表,索引的范围从0开始至局部变量表中最大的Slot数量。普通方法与static方法在第О个槽位的存储有所不同。非static方法的第О个槽位存储方法所属对象实例的引用。关于局部变量表的使用,将在字节码指令部分讲解. 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

5、每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,

持有这个引用是为了支持方法调用过程中的动态连接(Dynamic Linking)。在类加载阶段中的解析阶段会将符号引用转为直接引用,这种转化也称为静态解另外的一部分将在每一次运行时期转化为直接引用,这部分称为动态连接.

6、当一个方法开始执行后,只有2种方式可以退出这个方法:

方法返回指令︰执行引擎遇到一个方法返回的字节码指令,这时候有可能会有返回值传递给上层的方法调用者,这种退出方式称为正常完成出口。

异常退出︰在方法执行过程中遇到了异常,并且没有处理这个异常,就会导致方法退出。无论采用任何退出方式,在方法退出之后,都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在栈帧中保存一些信息。一般来说,方法正常退出时,调用者的PC计数器的值可以作为返回地址,栈帧中会保存这个计数器值。而方法异常退出时,返回地址是要通过异常处理器表来确定的,栈帧中一般不会保存这部分信息。

4、程序计数器(为每个线程私有):

程序计数器(Program Counter Register)是一块较小的内存空间(储存在栈中),可以看作是当前线程所执行字节码的行号指示器,指向下一个将要执行的指令代码,由执行引擎来读取下一条指令。更确切的说,一个线程的执行,是通过字节码解释器改变当前线程的计数器的值,来获取下一条需要执行的字节码指令,从而确保线程的正确执行。

为了确保线程切换后(上下文切换)能恢复到正确的执行位置,每个线程都有一个独立的程序计数器,各个线程的计数器互不影响,独立存储。也就是说程序计数器是线程私有的内存。如果线程执行Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的是Native方法,计数器值为Undefined。程序计数器不会发生内存溢出(OutOfMemoryError即OOM)问题。

JVM初识-JVM内存结构相关推荐

  1. JVM运行时内存结构学习

    学习JVM运行模型比较重要,先看一幅图片: 运行时数据区(内存结构) :  1.方法区(Method Area) 类的所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在这里定义.简单来说, ...

  2. JVM详解——内存结构

    如果有兴趣了解更多相关内容,欢迎来我的个人网站看看:耶瞳空间 一:JVM基本介绍 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,具体实现有很 ...

  3. JVM学习-Java内存结构(详细易懂)

    Java内存结构 1.JVM概述 2.程序计数器 2.1.定义 2.2.作用及特点解释 3.虚拟机栈 3.1.栈的特点 3.2.栈的演示 3.3.栈的问题辨析 3.4.栈的线程安全问题 3.5.栈内存 ...

  4. [转]JVM运行时内存结构

    [转]http://www.cnblogs.com/dolphin0520/p/3783345.html 目录[-] 1.为什么会有年轻代 2.年轻代中的GC 3.一个对象的这一辈子 4.有关年轻代的 ...

  5. JVM初识:堆内存、栈内存

    深入理解Java内存(图解堆栈) - 万物为铜 - 博客园深入理解Java内存(图解)--转载 深入理解Java内存(图解)https://www.cnblogs.com/lipeineng/p/83 ...

  6. Java 内存模型和 JVM 内存结构真不是一回事

    这两个概念估计有不少人会混淆,它们都可以说是 JVM 规范的一部分,但真不是一回事!它们描述和解决的是不同问题,简单来说, Java 内存模型,描述的是多线程允许的行为 JVM 内存结构,描述的是线程 ...

  7. 万万没想到,JVM内存结构的面试题可以问的这么难?

    在我的博客中,之前有很多文章介绍过JVM内存结构,相信很多看多我文章的朋友对这部分知识都有一定的了解了. 那么,请大家尝试着回答一下以下问题: 1.JVM管理的内存结构是怎样的?  2.不同的虚拟机在 ...

  8. 原创 | 万万没想到,JVM内存结构的面试题可以问的这么难?

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 223 篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) 在我的博客中,之前有 ...

  9. JVM之深入理解JVM内存结构(Java内存结构/Java内存区域)、Java内存模型

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点.而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚.比如本文我们要讨论的JVM内存结构.JAVA内存结构.JAVA内存 ...

  10. <JVM上篇:内存与垃圾回收篇>01-JVM与Java体系结构

    笔记来源:尚硅谷 JVM 全套教程,百万播放,全网巅峰(宋红康详解 java 虚拟机) 文章目录 1.JVM 与 Java 体系结构 1.1. 前言 1.2. 面向人群及参考书目 1.3. Java ...

最新文章

  1. 最大公约数 辗转相除法
  2. c++基础学习(07)--(类)
  3. python画海绵宝宝_《1,2,3到动物园》数数书,适合幼儿园小班宝宝亲子共读,从游戏中了解数字的概念...
  4. pthread_exit()
  5. NVIDIA的黑科技3:VXGI体素全局光照
  6. SerializeField和Serializable
  7. C# 笔记2 - 数组、集合与与文本文件处理
  8. --save-dev 与 --save的区别
  9. Ubuntu 18.04 无法上网
  10. WDF队列分析(3)
  11. centos7安装jdk1.8.0并配置JAVA_HOME环境变量
  12. 我为什么要开始写博客
  13. MapReduce: Simplified Data Processing on Large Clusters
  14. java宠物商店管理系统_Java实现宠物商店管理系统
  15. 知识图谱:语义网络、语义网、链接数据、知识图谱
  16. 服务器怎么安装exis系统,exis 服务器安装
  17. Easyui后台管理界面设计
  18. 携程手机端网页设计效果图
  19. HTML如何自动播放网易音乐,教大家网易云音乐打开自动播放功能的流程
  20. 多图!2020年互联网大厂中秋礼盒PK!阿里走情怀,腾讯更复古,最走心的是......

热门文章

  1. 【Linux】之 从源代码安装软件(HelloWorld)
  2. 微警务:网上公安服务一键开启
  3. go语言-LiteIDE 安装及使用教程
  4. 调用情迁机器人发送微信或者QQ消息等即时通讯消息
  5. 文献阅读-深度学习跨模态图文检索研究综述
  6. 深度学习领域最新的技术(CV、NLP)
  7. 为什么提倡面向接口编程
  8. 一些生物信息学常用的分析法的介绍
  9. 记:应聘招银网络科技 测试开发工程师
  10. 32位Linux系统时间截止,linux – 如果系统设置为2038年以后的日期,则ntpdate失败