类加载机制 https://blog.csdn.net/xu768840497/article/details/79175335
类的生命周期
1、加载:读取二进制内容
2、验证:已验证class文件格式规范、语义分析、引用验证、字节码验证
3、准备:分配内存、设置类static修饰的变量初始值
4、解析:类、接口、字段、类方法等解析
5、初始化:为静态变量赋值;执行静态代码块
6、创建实例对象
7、从JVM方法区中卸载
类加载器
1、Bootstrap loader:核心类库加载器,C/C++实现,无对应java类:null加载JRE_HOME/jre/lib目录,或者用户配置的目录 JDK核心类库rt.jar
2、Extension Class Loader:扩展类库加载器,ExtClassLoader实例:加载JRE_HOME/jre/lib/ext目录,JDK拓展包,或者用户配置的目录
3、application clas loader:用户应用程序加载器,AppClassLoader.path制定的目录,用户应用程序class-path 或者java命令运行时参数-cp..
1、启动类加载器(Bootstrap ClassLoader),它是属于虚拟机自身的一部分,用C++实现的,主要负责加载
<JAVA_HOME>\lib目录中或被-Xbootclasspath指定的路径中的并且文件名是被虚拟机识别的文件。它
等于是所有类加载器的爸爸。
2、扩展类加载器(Extension ClassLoader),它是Java实现的,独立于虚拟机,主要负责加载<JAVA_HOME>\lib\ext目录中或
被java.ext.dirs系统变量所指定的路径的类库。
3、应用程序类加载器(Application ClassLoader),它是Java实现的,独立于虚拟机。主要负责加载用户类路径(classPath)上
的类库,如果我们没有实现自定义的类加载器那这玩意就是我们程序中的默认加载器。
查看类对应的加载器:
API:java.lang.Class.getClassLoader()
如果这个类是有bootstrapClassLoader加载的,那么这个方法在这种实现中将返回null
类的卸载
满足两个条件时会被卸载
1、该Class所有的实例都已被GC
2、加载该类的ClassLoader实例已被GC
验证方式:JVM启动中增加-verbose:class参数,输出类加载和卸载的日志信息
双亲委派模型
为例避免重复加载,由下到上逐级委托,由上到下逐级查找。
通一个类加载器不会加载多同一个类,判断方式ID+类名。
热部署:使用不同的类加载器加载改变之后的Class文件
垃圾收集
自动垃圾收集
自动垃圾收集是查看堆内存,识别正在使用哪些对象以及哪些对象未被删除以及删除未使用对象的过程。
使用中的对象或引用的对象意味着程序的某些部分任然尾喉指向该对象的指针。
程序的任何部分都不在引用为啥使用的对象或未引用的对象,因此可以回收未引用对象使用的内存。
在c这样的编程语言中,分配和释放内存是一个手动的过程,在Java中,,接触分配内存的过程是由垃圾收集器自动处理
如何确定内存需要被回收
该过程的第一步称为标记。这是垃圾收集器识别哪些内存真正在使用而哪些不在使用的地方
可达性分析算法
将对象及其引用关系看做一个图,选定一个活动的对象做为GC Roots。然后跟踪引用链条,如果一个对象和GC Roots之间不可达,也就是不存在引用,
那么即可认为是可回收的对象
可作为GC Root的对象
1、虚拟机栈中正在引用的对象
2、本地方法栈中正在引用的对象
3、静态属性引用的对象
4、方法区常亮引用的对象
引用类型:
强引用(StrongReference):最常见的普通对象引用,只要还有强引用指向一个对象,就不会被回收
软引用(SoftReference):JVM认为内存不足时,才会试图回收软引用指向的对象。(缓存场景)
弱引用(WeakReference):虽然是引用,但是随时可能被回收掉
虚引用(PhantomReference):不能通过它访问的对象。对象被finalize以后,执行指定 逻辑的机制(Cleaner)
可达性级别:
强可达(Strongly Reachable)一个对象可以有一个或多个线程可以不通过各种引用访问到的情况
软可达(Softly Reachable):当只能通过软引用才能访问到对象的状态
弱可达(Weakly Reachable):只能通过弱引用访问时的状态。当弱引用被清除的时候,就符合销毁条件
幻想可达(Phantom Reachable):不存在其他引用,并且finalize过了,只有幻想引用指向这个对象,
不可达(unreachaable):意味着对象可以被清除了
调优基本概念
在调整性能时,JVM有三个组件
1、堆大小调整
2、垃圾收集器调整
3、JIT编译器
大多数调优选项都与调整堆大小和为您的情况选择最合适的垃圾收集器有关。
JIT编译器对性能也有很大影响,但很少需要使用教新版本的JVM进行调优。
通常在调优Java应用时。重点是一下两个主要目标之一
响应性:应用程序或操作系统对请求的数据进行相应的数据,对于专注于相应性的应用程序,长的暂停时间
是不可接受的,重点是在短时间内做出回应
吞吐量:侧重于在特定的时间段内最大化应用程序的工作量,对于专注于吞吐量的应用程序,高暂停时间是
可以忍受的。由于高吞吐应用程序在较长时间内专注于基准测试,因此不需要考虑快速响应时间
GC调优思路:
1、分析场景
启动速度慢;偶尔出现相应慢于平均水平或者出现卡顿
2、确定目标
内存占用、低延时、吞吐量
3、收集日志
通过配置参数配置手机GC日志;通过JDK工具查看GC状态
4、分析日志
使用工具辅助分析日志,查看GC次数,GC时间
5、调整参数
切换垃圾收集器或者调整垃圾收集器参数
垃圾收集算法
标记-清除
复制算法
标记整理算法
垃圾收集算法:
老年代分带收集算法:
引用类型和可达性级别:
可达性分析算法:
垃圾收集器(并发收集,CMS):
垃圾收集器(并发收集器G1):
垃圾收集器(并行,多线程):
垃圾收集器(并行收集器、已放弃维护):
垃圾收集器(串行,单线程):
垃圾收集器组合(完整图):
JVM几个常见内置命令:
JAVA内置工具-Jconsole:
JAVA内置命令-javap:
JAVA内置命令-jcmd:
JAVA内置命令jhat:
JAVA内置命令-jinfo:
JAVA内置命令-jmap:
JAVA内置命令-JPS:
JAVA内置命令-jstack:
JAVA内置命令-jstat被jcmd命令替代:
JDK内置工具-JvisualVM: