标签:屏蔽 asp 调用 解析 不记录 内容 逻辑 bsp cti
一、JVM基础(JVM是什么? JRE是什么? JDK是什么?)
a) JVM是什么?
编写的Java文件编译成class文件,class文件放入JVM中转义机器码,让机器执行
i. Java跨平台:一次编译到处运行原理,是因为安装了不同文件操作系统的JDK(JVM), 字节码(class)文件适配不同底层的操作系统(不同操作系统的文件操作/描述符不同,不同操作系统的句柄也不同),所以通过字节码(class)文件和JVM帮我们屏蔽了底层的操作系统,是字节码(class)文件做中间语言实现的跨平台,所以结论:JVM软件层面屏蔽了底层硬件、指令层面的细节。
(知识扩展,C/C++是跨平台的吗?是,但这是层次问题,原因是:C/C++ 是通过编译器编译实现的跨平台,需要在编译级别去兼容底层不同的操作系统和不同实现,所以C/C++编写代码时不同操作系统下的编码不同)
ii. 如上图所示:JVM屏蔽了所以的Platforms(平台),JVM是JRE中的一部分,JVM分为两部分:Client VM和Server VM,JDK1.8以后就没有了Client VM (因为机器是64位操作系统,支持内存理论可达无限,而Client VM最大只能支持内存4G,原因:机器是二进制存储,如果系统是32位,那2^32=4G,操作系统最大只能支持4G)
b) JRE是什么?
JRE(Java Runtime Environment) :JVM + Java运行时的底层类库(大部分是使用C/C++写的)
c) JDK(Java Development ToolKit) : JRE + 编辑Java文件所需要的编译器和监控JVM的监控工具
二、为什么要学JVM?
因为面试造火箭,工作拧螺丝,玩笑,继续
a) 为什么Java从1995年支撑到如今?为什么Java在企业级开发占据领域?为什么Java在开发语言中占据第一?
是因为内存管理,因为编写Java不需要关注内存问题,不需要关心创建对象后回收问题,所以我们的精力可以专注在业务实现上面;相比C/C++,比如创建数组还需要malloc分配内存,并且还需要自己手动free释放内存
b) 但As the saying goes, every coin has two sides(俗话说,每个硬币都有两面),因为在编写代码时不需要关注内存管理时,所以更需要了解内存问题。
如果发生内存出现问题或内存泄漏/溢出,无知将无措,有追求的程序员要知其然知其所以然,所以要学JVM。
三、JVM运行时数据区
a) 什么是运行时数据区?学了有什么用?怎么学?
运行时数据区:顾名思义,代码在运行时创建的数据区。运行时数据区又分为数据区和指令区
Java类内容只包含:数据、指令、控制三种(常量、静态变量、成员变量为数据;运算是指令;结束返回是控制)
(知识扩展:计算机也包含三流[数据流、指令流、控制流])
b) 程序计数器:类似与计算机指令寄存器存储在RAM里,指向当前线程正在执行的字节码指令的地址(行号):Java最小的执行单位是线程,线程执行指令,操作系统CPU运行指令,CPU运行指令是由不稳定的调度策略调度,而调度策略是基于轮转时间片(执行顺序是抢占式),所以当前时间点分配给哪个指令是不确定的,未抢占成功的指令将会挂起,而线程主要作用是运行指令(不记录当前指令运行状态),指令状态是由程序计数器记录的。指令要恢复执行状态就要去找到自己私有的程序计数器中的地址(行号)
程序技术器是线程私有/独享的一个变量
c) 虚拟机栈:
推导:虚拟机栈——》栈——》数据结构——》存储数据
解释:存储当前线程运行方法时所需要的数据、指令、返回地址
i. 类方法是由线程执行,而线程是一个执行者,不会存储数据。线程执行类方法时的数据结构就是虚拟机栈
ii. 虚拟机栈FILO(first-in last-out,先进后出):基础单位是栈帧,其中一个方法就是一个栈帧,每个栈帧长度不一。栈帧包含:局部变量表、操作数栈、动态链接、出口等;
引申:当一个方法A调用另一个方法B时,在虚拟机栈内的位置是B在A的前面(因为栈是先进后出)
类成员引用变量值是存储在Heap(堆)内,所以在执行方法应用到成员引用变量时会有栈指向堆的操作(栈帧内局部变量表存储成员引用变量是存储指向堆的地址)
iii. 虚拟机栈是有大小的,超出大小会报StackOverflowError错误
d) 本地方法栈:带native修饰的方法是本地方法(本地类库,大多由C/C++语言编写),过程可对比虚拟机栈
e) 方法区:根据版本呢划分,版本<=1.6存储的是类信息、常量、静态变量(常量、静态变量是存储在方法区内,成员引用变量是存储在堆内,局部变量是存储在虚拟机栈的栈帧内;版本>=1.7,字符串常量迁移到堆内
f) Head(堆)
线程共享:方法区和head(堆)
线程独享:程序计数器、虚拟机栈、本地方法栈
如上逻辑图不是存储在线程内是存储在寄存器内
四、JVM内存模型
理想状态下不触发大对象threshold,不触发age TLAB
新生代是复制回收算法
当申请一个8M的空间会放入到eden区,如果程序运行过程中再去申请一个1M的空间,那正在使用的8M空间会进入空间担保,进入老年代,新生代eden会进行一次Minor gc(基于新生代是复制回收算法,就会触发一次Minor gc/young gc),恢复原有空间,并把1M的空间放入eden区。
最大的变化就是把永久代变成Meta Space(元空间)
优点:再也不需要受到perm size 的限制,Meta Space 是可以无限扩容
缺点:Meta Space不属于堆,Meta Space不可控(会抢占别的区块空间)
假设内存有2G,元空间有256M,Heap(堆)Xms 256m/Xms 1g,当元空间自动扩容超过1G以上,那heap(堆)空间就会异常
缺点解决方案:定义best practice MetaSpace大小
(知识扩展:
数据要存储,那数据就要回收,回收就要有垃圾回收算法
垃圾回收算法——》垃圾回收器
垃圾回收算法决定了垃圾回收器,不同的区块选用不同的垃圾回收算法,也就是选用不同的垃圾回收器)
标签:屏蔽 asp 调用 解析 不记录 内容 逻辑 bsp cti
原文地址:https://www.cnblogs.com/chai-blogs/p/12593616.html