1、HotSpot VM的结构
在.class 文件下执行 javap -v XXX.class 可以看到反编译文件
jps:查看进程
栈:
跨平台、指令集小(8)、指令多、执行性能比寄存器差
寄存器:
对应硬件、指令集大(16)、指令少、执行性能高
在反编译字节码中
常见虚拟机 HotSpot、JRockIT、J9
idea可视.class文件插件
类加载过程
初步分为三个过程,加载、链接、初始化
1、加载阶段
重要加载器 大范围分为引导类加载器、自定义类加载器
【根加载器】 Bootstrap
【平台类加载器(扩展类加载器)-->1.8(ExtClassLoader)】 PlatformClassLoader
【用户类加载器】 AppClassLoader
什么时候需要自定义加载器
需要扩展加载类、隔离加载类、修改类加载方式、防止代码泄露
什么是双亲委派机制:
类需要加载的时候先会委托上一级的加载器进行加载,一直往上,如果上层不加载在向下传
--保证核心数据不被篡改
2、链接阶段
链接分为: 验证、准备、解析
运行时数据区
重要组成: 方法区、堆(这两个共享)、程序计数器、本地方法栈、虚拟机栈(这三个私有)。
程序计数器
虚拟机栈
虚拟机栈是私有的,其内部保存的是一个个的栈帧,对应着一次次的java方法调用。主管java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回
使用 -Xss
栈存储单位,其中包含 局部变量表*、操作数栈*、动态链接、方法返回地址
局部变量表
操作数栈
首先由pc计数器记录要执行的代码,要操作的数先入操作数栈中,在出栈到局部变量表中存放,需要做的数据操作(如加减乘除)需要执行引擎来完成
动态链接
动态链接说的是每一个栈帧都指向一个运行时常量池
方法调用
非虚方法: 能确定调用的方法是非虚方法,如 static、final修饰的,构造方法,private方法
非虚指令: invokestatic、invokespecial
虚指令: invokevirtual、invokeinterface
方法返回地址
指的是方法中调用其他方法结束后方法下一步需要执行的地址值
本地方法库
其作用是融合不同的编程语言为java所调用
本地方法栈(运行时数据区)
管理本地方法的调用,主要是管理C、C++方法的调用
堆
设置堆空间大小: -Xms 初始大小 -Xmx 最大大小 ,初始大小是: 电脑物理内存 / 64,最大内存 : 电脑物理内存 / 4
查看jvm运行程序的指令: jps。查看jvm进程使用情况 :jstat -gc 线程号。
控制新生代与老年代的占比指令 : -XX:NewRatio=2 表示新生代占1,老年代占2
-XX:NewRatio=4表示新生代占1,老年代占4
查看新生代与老年代比例: jinfo -flag NewRatio 进程号
新生代内部空间区分 -XX:SurvivorRatio=8
在幸存者区一直存活了15次后进入老年区,默认是15,也可以通过
-XX:MaxTenuringThreshold=<N>来设置
GC 回收器:
TLAB:在栈中会默认分配大小为Eden1%的私有栈空间,可以使用
-XX:TLABWasteTargetPercent 来指定百分比
常用参数:
优化之逃逸分析
优化之标量替换
方法区(元空间)
元空间使用的是本地内存
对元空间的设置
-XX:MetaspaceSize 设置元空间的初始大小 默认约为21M
-XX:MaxMetaspaceSize 设置元空间的最大大小 默认没有限制
内存泄露与内存溢出
内存泄露指的是栈中的对象有被指向但是没被使用。
内存溢出指的是数据在内存中放不下。
方法区主要存储
类型信息、常量、静态变量、即时编译器编译后的代码缓存
方法区重要组成部分:运行时常量池
常量池保存的是符号引用
运行时常量池: 常量池运行是的表现形式
方法区的演进
永久代为什么会被替换
对象实例化的方式
对象实例化过程
1:加载类元信息。 2:为对象分配内存。3:处理并发问题。4:属性的默认初始化。
5:设置对象头信息。6:属性的显示初始化、代码块中初始化、构造器中初始化
对象加载图解
对象的访问方式有两个:1、直接访问 2、句柄访问
直接访问
句柄访问
执行引擎
HotSpot虚拟机拥有解释器和及时编译器(JIT)两种的,两者并不是先后执行的关系,而是优点共存,解释器相应快,及时编译器执行更快
String Table
垃圾回收
垃圾标记阶段之引用计数算法(java虚拟机并不使用)
垃圾标记阶段之可达性分析算法(java虚拟机使用)
一般在将要回收的区域之外都可以临时的看做Roots,比如Eden回收老年区可以当做Roots
清除阶段
标记-清除算法(Mark-Sweep)
复制算法
标记-压缩算法(Mark-Compact)
System.gc() 触发的是Full GC
内存溢出问题
内存泄露问题
垃圾回收器的并行与并发
软引用
弱引用
垃圾回收器
Serial收集器
PerNew回收器
Parallel Scavenge回收器
CMS回收器
G1回收器
/**
* -Xms:512m 设置堆空间初始值 默认为物理内存的 1/64
* -Xmx:512m 设置堆空间最大值 默认为物理内存的 1/4
* -XX:+PrintGC 打印简单的GC日志
* -XX:+PrintGCDetails 打印详细的GC日志
* -XX:+PrintGCTimeStamps 输出GC时间戳
* -XX:+PrintGCDateStamps 输出GC具体时间
* -XX:+PrintHeapAtGC 在GC前后输出堆信息
* -Xloggc:../logs/gc.log 日志文件输出
* -XX:NewRatio=2 设置新生代与老年代的占比 默认 新:老 1:2
* -XX:SurvivorRatio=8 设置Eden区于幸存者区的占比 默认 Eden:s0:s1 8:1:1
* -XX:-UseAdaptiveSizePolicy 关闭自适应内存分配 默认开启 -XX:+UseAdaptiveSizePolicy
* -Xmn: 设置新生代的空间大小
* -XX:MaxTenuringThreshod=<N> 设置多少次存活后进入老年区
* -XX:TLABWasteTargetPercent 指定每个线程在栈中初始的私有栈空间
* -XX:+PrintFlagsFinal 查看所有最终的参数
* -XX:+DoEscapeAnalysis 开启逃逸分析
* -XX:+PrintEscapeAnalysis 查看逃逸分析结果
* -XX:+EliminateAllocations 开启标量替换 默认是开启
* -XX:MetaspaceSize 设置元空间的初始大小 默认约为21M
* -XX:MaxMetaspaceSize 设置元空间的最大大小 默认没有限制
* -XX:StringTableSize 设置StringTable的长度
* -XX:+PrintCommandLineFlags 查看命令行相关参数(包含使用的垃圾收集器)
* -XX:+UseSerialGC 设置虚拟机使用Serial收集器
*/
--学习资源尚硅谷
前204章