JVM成为java虚拟机,介绍就不用多说了。如果要学习jvm我们必须需要了解一下自己本地安装的jdk吧
JVM分为两种模式:client和server
Server VM 是由jvm根据运行时的环境(操作系统的环境)自动判断
mixed mode 混合模式(jvm是解释性语言也支持编译)
jps
jinfo -flags 进程id
-XX:MaxHeadSize 堆的最大值
-XX:MaxNewSize 新生代的最大值
-XX:MinHeapDeltaBytes
-XX:NewSize 新生代大小
-XX:OldSize:老生代大小
jmap -head 进程id (看内存信息)
文档 https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jmap.html
JDK JRE JVM三者关系
接下来要掌握几个问题
为什么可以使用Object类?
在jvm启动运行的时候,已经让根classLoader加载rt.jar下面的class。Object位于rt.jar包下面
java启动类是那个?
双亲委派与沙箱安全机制?
双亲委派是下层的classLoader先不加载让上层的classLoader先加载,将加载委派给上一层进行
沙箱安全机制,保证安全性,不让jdk的代码被篡改。
jvm运行数据区
类加载器(ClassLoader)
classLoader加载并初始化Car.class文件生成一个Car Calss模板类(相当于一个模板信息,将car对象的属性和方法都存放进去)
反射的三种方式
- 通过Object类的getClass方法来获取
- 使用.class的方式
- 使用Class.forName方法
类加载器ClassLoader2
为什么会有Native方法
java不能操作底层代码,本地接口的作用是融合不同的编程语言为java所用
本地方法栈(运行C、C++方法)
栈是一种数据结构。
栈:先进后出 队列:先进先出
每一个函数对应一个栈帧。
栈帧里面包含 局部变量表、操作数栈、栈数据区。
PC寄存器
每个线程都会有一个程序计数器,是线程私有的,就是一个指针,指向方法区的字节码(用来存储指向下一条指令,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计。
方法区(Method Area)
方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单说,所有定义的方法信息都保存在该区域,此区域属于共享区间。
静态变量+常量+类信息(接口/构造方法)+运行时常量池也存在方法区
方法区是接口是规范。元空间是对方法区的实现
栈区(java栈 运行java方法)
stack栈是什么?
栈也叫栈内存,主管Java程序的运行,是线程创建的时候创建,它的生命周期跟随线程的生命周期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题。
存放8种基本类型的变量+ 对象的引用变量+实例方法都在栈内存分配
堆(Heap)
堆分三块: 新生代,养老区,永久区
对象在创建的时候被分配到新生代,经过一定的垃圾回收会回到养老区。永久区放不变的对象。(全局变量的定义放在永久区)
一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的,类加载器读取到类文件后,需要把类、方法、常变量放到堆内存,保存所有引用类型的真实信息,方便执行器执行。
新生代:
元空间(非堆):
老年代:
Eden:所有对象新生都会放到这个里面
栈+堆+方法区交互关系