【Java进阶营】Java架构师入门到精通之JVM总体架构

什么是JVM?

JVM(Java Virtual Machine,Java虚拟机)

用记事本写第一个java程序HelloWorld

第一步:写java源代码程序:HelloWorld.java

第二步:编译java源代码程序,生成HelloWorld.class文件,字节码文件

第三步:运行程序.(在JVM里运行的)

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

对于Java程序员来说,JAVA虚拟机底层的指令,不是我们核心关注的内容,我们关注的是我们写的java程序在jvm中运行时需要的内存,内存是由JVM自动管理的,由于程序或硬件的原因可能会出现内存泄漏或溢出的问题导致运行的程序崩溃,不了解JVM的内存结构和各个内存区域的工作职责,将对解决这类问题带来很大的麻烦,所以学习java到一定程度的时候,是必须要学习jvm里的知识点的,我们先粗略地了解一下整个JVM的构架,来开始我们的学习:

d7be06fc06622a5d435835a77f07daaa_1550523-20190911172546749-1868939202.png

JVM****被分为三个主要的子系统

(1)类加载器子系统—执行.class编译后的文件,载入到jvm的体系中,然后进行初始化的操作,把相关的数据放到内存中的某些区域,做具体的内存分配的操作

(2)运行时数据区(我们核心关注这里的栈、堆、方法区)【这里面所存放的是类加载加载后的一些数据】

(3)执行引擎—是从内存中(可以任务是运行时数据区)获取相关数据来执行,执行后在把数据返还到内存中

1.解释器 :运行字节码文件

2. 编译器:把字节码文件(.class文件)编译成根据当前操作系统能够执行的文件,他决定跨平台

3. 垃圾回收器:会把内存中产生的垃圾数据进行回收清理,进行释放内存,清空时会根据jvm中垃圾回收算法进行回收,且自动进行回收,我们主要调优就是调这里,通过合适的算法进行对jvm的优化处理,避免出现卡顿,内存溢出等情况,尽可能的高效运行

4.JIN:(java本地接口)—怎么调用C语言的这些代码

5.本地方法库:本地方法栈为虚拟机使用到的 native 方法服务

虚拟机栈

虚拟机栈(Java Virtual Machine Stacks)和线程是紧密联系的,每创建一个线程时就会对应创建一个Java栈,所以Java栈也是"线程私有"的内存区域(每个栈与每个栈互不影响),这个栈中又会对应包含多个栈帧(栈帧就是方法),每调用一个方法时就会往栈中创建并压入一个栈帧(创建栈帧),栈帧是用来存储方法数据和部分过程结果的数据结构,每一个方法从调用到最终返回结果的过程,就对应一个栈帧从入栈到出栈的过程。

虚拟机栈是一个后入先出的数据结构,线程运行过程中,只有一个栈帧是处于活跃状态的,被称为"当前活动帧栈",当前活动帧栈始终是虚拟机栈的栈顶元素。

12a4be2dbd34910b449dd5232624ff5f_1550523-20190911172620233-464686784.png

方法区

方法区(Method Area)是用于存储类结构信息的地方,包括常量池、静态变量(不易过多的创建静态的变量,因为类加载器只要一加载就会把静态变量加载到方法区中,导致运行效率降低,减小其他内存区域)、构造函数等类型信息,类型信息是由类加载器在类加载时从类文件中提取出来的。

方法区同样存在垃圾收集,因为用户通过自定义加载器加载的一些类同样会成为垃圾,JVM会回收一个未被引用类所占的空间,以使方法区的空间达到最小, 但是方法区的垃圾不易被回收。

方法区中还存在着常量池,常量池包含着一些常量和符号引用(加载类的连接阶段中的解析过程会将符号引用转换为直接引用)。

方法区是线程共享的。

堆(heap)是存储java实例或者对象的地方,是GC的主要区域,同样是线程共享的内存区域。也重点学习的地方。

案例分析一:

72ae28fe4bcaff52ba51aeff21cd3ce4_08fcba534909c5fd5772e00370be4ae3813.png


2019-10-09新增开始

104cabf1788ff8089ce250c90507622c_835e9c35550e81f716f271ae99944d55922.png

2019-10-09新增结束


案例分析二

5401afaa2ef7e139bbb7c3ef5da043a6_28e9dd8fd95596a9a9f77185a270701f96b.png


2019-10-09新增开始

43b6d2166ff96c73ca18e0a951259a94_f858cde5d17c869469062f8328d00219bc7.png

2019-10-09新增结束


上面main方法中运行的程序过程如下:

(1)用户创建了一个Student对象,运行时JVM首先会去方法区寻找该对象的类型信息,没有则使用类加载器classloader将Student.class字节码文件加载至内存中的方法区,并将Student   类的类型信息存放至方法区。在面试中被问到并发知识的时候,大多都会被问到“请你说一下自己对于AQS原理的理解”。下面给大家一个示例供大家参加,面试不是背题,大家一定要假如自己的思想,即使加入不了自己的思想也要保证自己能够通俗的讲出来而不是背出来。在此我向大家推荐一个架构学习交流圈。交流学习伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

(2)接着JVM在堆中为新的Student实例分配内存空间,这个实例持有着指向方法区的Student类型信息的引用,引用指的是类型信息在方法区中的内存地址。

(3)在此运行的JVM进程中,会首先起一个线程跑该用户程序,而创建线程的同时也创建了一个虚拟机栈,虚拟机栈用来跟踪线程运行中的一系列方法调用的过程,每调用一个方法就会创建并往栈中压入一个栈帧,栈帧用来存储方法的参数,局部变量和运算过程的临时数据。上面程序中的stu是对Student的引用,就存放于栈中,并持有指向堆中Student实例的内存地址。

(4)JVM根据stu引用持有的堆中对象的内存地址,定位到堆中的Student实例,由于堆中实例持有指向方法区的Student类型信息的引用,从而获得add()方法的字节码信息,接着执行add()方法包含的指令。

总结

  1. 所有线程共享的内存数据区:方法区,堆。而虚拟机栈,本地方法栈和程序计数器都是线程私有的。
  2. 存放于栈中的东西如下:
    • 每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象)。对象都存放在堆区中。
    • 每个栈中的数据(基础数据类型和对象引用)都是私有的,其他栈不能访问。
    • 方法的形式参数,方法调用完后从栈空间回收
    • 引用对象的地址,引用完后,栈空间地址立即被回收,堆空间等待GC
  3. 存放于堆中的东西如下:
    • 存储的全部是对象,每个对象包含一个与之对应的class信息
    • Jvm只有一个堆区(heap)被所有线程共享,堆区中不存放基本类型和对象引用,只存放对象本身
  4. 存放于方法区中的东西如下:
    • 存放线程所执行的字节码指令
    • 跟堆一样.被所有线程共享.方法区包含:所有的class和static变量
    • 常量池位于方法区中,见如下图示说明

2bcb630897ffa02ea6eddcb271f33466_ea49c3b2342055586553e6ae13bff08fe10.png

阿里巴巴编码规范 基础技能认证 考题分析(考题+答案)_链接:https://pan.baidu.com/s/1CTGGf4IM-mDKU4FO82yAMw
提取码:r7y9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值