Java
一、jvm模块
-
jvm是什么?
是一用用于计算设备的规范,虚构出来的计算机,在计算机上仿真模拟各种计算机功能来实现
-
jvm 作用是什么?
java中所有类必须装载jvm中才能运行,这个装载工作有jvm装载器完成,.class类型文件能在jvm虚拟器中运行,但不能直接在系统中运行,需要jvm解释给系统,同时需要java类库,这就是人机交互,jvm作用
-
jvm内存模型
方法区(线程共享)
常量,静态变量 以及方法信息(修饰符,方法名,返回值,参数等)、类信息等
堆(线程共享)
实例对象, 内存最大的一块
栈(虚拟机栈-线程私有)
生命周期、线程结束,栈内存就释放了,主要存储 8大基本类型 + 对象饮用 + 实例方法
本地方发栈 线程隔离
主要就是Java里面 native修饰的方法,指责与虚拟机栈一样,只不过针对的是 c++曾
程序计数器 线程隔离
保存的是 jvm指令集,程序计数器总是指向下一条指令地址,生命周期与线程生命周期一样 -
类加载器都有哪些?这里只介绍java
bootstrap classloader: 引导类加载器 c++编写,用于家在java核心库,jir/lib目录下jar包,无法直接获取
Extension classloader:扩展类加载器 负责jir/lib/ext目录下jar包 或 -D java.ext dirs 制定目录下的jar包
Application classloader 系统类加载器,负责 java-classpath 或 -D java classpath制定目录下的jar包
Custom classloader 自定义类加载器 -
类加载器作用?
将class字节码加载到内存,并将这些动态数据转换成方法区运行时数据结构,然后在堆中形成这个类的class对象,作为方法区中数据访问路口
本质就是 将字节码加载到内存里面 -
java文件加载过程?
- 双亲委派
-
双亲委派优缺点
优点: 保证类的安全性,不管被哪个类加载,都会委托给引导类加载器加载,也就是父类加载器,只有父类加载不了,才交给子类, 这样能保证创建的对象是一个
缺点:子类加载器可以使用父类加载器创建的类,而父类加载器不能使用子类加载器创建的类 (所以要破坏双亲委派机制) -
破坏双亲委派机制的方式
自定义类加载器, 重写 loadclass 方法
使用线程上下文类 serviceloader ,使父类加载器可以加载子类
二、 Java内存模型
-
什么是Java内存模型?JMM
就是一种符合内存模型的规范,屏蔽硬件和操作系统系统的差异,保证Java在各个平台内存运行的效果一致
Java内存模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程中是用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。 -
JMM作用
工作内存与主内存之间数据同步过程
-
JMM 实现
java提供了一系列和并发处理相关的关键字,比如 volatile synchronized final 等 其实就是 原子性,可见性,有序性
-
java对象模型
三、GC相关
-
垃圾算法有哪些?
复制算法:
将内存分为大小相等的两块内存区域,每次只使用一块,当这一块内存存满后将存活的对象复制到另一块内存上,将剩余的已使用的内存回收
优点:算法简单,内存效率高,不易产生内存碎片
缺点:内存使用率被缩减了原来的一半,存入对象增多时,效率大大降低标记-清除:
分为两个阶段:
1.标记所有需要回收的对象
2.回收被标记对象所占内存空间
缺点:算法效率较低, 会产生大量不连续内存碎片,存储大对象时找不到可利用空间等问题标记整理:
标记阶段和标记清除很像,但后面不是清理对象,而是将存活对象移至内存的一端,然后清除边界外内容
分代回收:
新生代 : 老年代 = 1:2 默认
新生代里面又分为, eden , survivor from, survivor to
按照 8:1:1的关系分配,
每次只使用eden和一块survivor空间, 当eden和srvivor from 内存不足时,会出发一次GC,将这两块存活下来的对象复制到另一块survivo to 中, 然后清理eden和 survivor from 内存空间
如果 srvivor to内存空间无法存储某个对象时,则将对象存入老年代 (空间担保);此时 survivor from 和 survivor to互换,如此循环,当一个对象经历过一次GC未被清除, 该对象年龄+1,默认 15 次 移至老年代
新生代 一般是 复制算法 / 标记-清除
老年代 标记-整理算法分区回收:
-
垃圾回收器有哪些?
serial垃圾回收器
单核或单线程,采用复制算法,垃圾回收的同时,暂停所有工作,直至垃圾回收结束, 简单高效,没有线程交互开销,可以获得最高效率的单线程垃圾收集效率, client模式下默认的新生代垃圾回收器
PartNew垃圾回收器
serial 垃圾回收器的多线程版本, 同样采用复制算法,在垃圾回收过程中同样会暂停其他所有工作,直至垃圾回收完成,jvm servicer端新生代垃圾回收器
ParNew收集器默认开启和CPU数目相同的线程数,可以通过-XX:ParallelGCThreads参数限制垃圾收集器的线程数。parrallel scavenge 垃圾回收器
新生代垃圾回收器,多线程, 同样采用复制算法,重点关注的是 程序达到一个可控制的吞吐量,可以高效率的利用cpu, 主要适用于后台运算不需要太多交互任务,自适应调节策略也是 parallel scavenge 与 partNew 的重要区别
吞吐量 = 运行用户代码时间 / 运行用户代码时间 + 垃圾回收时间serial old 垃圾回收器
单线程垃圾回收器,serial 老年代版本,采用标记-整理算法 jvm client 默认老年代垃圾回收器
parallel old 垃圾回收器
paraelle scavenge 的老年代版本,使用多线程 标记-整理算法
CMS垃圾回收器
老年代垃圾回收器,主要目标最短垃圾回收停顿时间,和其他老年代回收算法 标记-整理不同的是,它采用 多线程 标记-清除算法, 最短的垃圾回收回收停顿时间可以给人机交互最好的体验
CMS工作机制
初始标记:标记一下gcroot 能直接关联的对象,速度很快,同样暂停其他所有工作
并发标记:进行GCRoot跟踪的过程,和用户线程一起工作,不需要暂停所有工作
重新标记:修正并发标记过程中,由于程序运行导致标记产生变动的那一部分记录,仍然暂停所有工作的线程
并发清除:清除GCRoot 不可达对象和工作线程一起,不需要暂停所有线程工作G1垃圾回收器
不会像传统垃圾回收器一样等内存满了时候进行垃圾回收,而是没满时就进行了回收,这样保证了垃圾回收最短停顿时间,最大吞吐量
应用场景:面向多cpu和大内存服务场景,例如:电商秒杀服务器,多路直播服务器
特征:弱化分代,强化分区,能实现一些更细更复杂的功能
分区的好处
1.垃圾回收过程和其他工作线程能够并行工作,避免STW
2.不同区域可同时回收,并发性高,更适应多核服务器
3.可以先回收一部分,回收更快
4.可以建立停顿预测模型,用户可以设定垃圾回收最长时间 -
判断可回收对象的方法有哪些?
应用计数法
一种内存管理技术,用于跟踪每个对象被引用的次数。当某个对象的引用次数变为0时,表示没有其他对象再引用它,此时该对象可以被回收。这种方法通过在对象头中添加一个计数器来记录对象的被引用次数,从而实现自动资源管理
引用计数法实现流程
1. 分配对象:当新对象被分配时,其引用计数初始化为1。例如,在Java中,当一个新对象被创建时,它的引用计数会被设置为1。
2. 更新引用:每当一个对象的引用发生变化时,相应的引用计数也会更新。例如,如果有一个对象A被另一个对象B引用,那么对象A的引用计数会增加1;如果B不再引用A,那么A的引用计数会减少1。
3. 回收对象:当某个对象的引用计数变为0时,表示没有其他对象再引用它,此时该对象可以被回收。例如,如果对象A的引用计数变为0,那么A可以被回收。
引用计数法的优缺点
优点:
实现简单:引用计数法的实现相对简单,不需要复杂的垃圾回收算法。
效率较高:由于没有复杂的垃圾回收过程,程序的运行效率较高。
缺点:
循环引用问题:在有循环引用的情况下,即使两个对象都不再被使用,它们的引用计数也不会变为0,导致这些对象无法被回收。
内存泄漏:在某些情况下,由于引用计数的错误管理,可能会导致内存泄漏。可达性分析算法
通过一些列成为GCRoot对象最为根节点,从这些节点开始,向下搜索,搜索过程所走过的路径叫引用链,如果某个对象到GCRoot间没有任何引用链相连,称之为 不可达,也就是这个对象不再被使用
-
Gc root 对象
- 虚拟机栈中应用的对象, 例:各个线程调用堆栈中 参数,局部变量,临时变量等
- 方法区中静态属性引用的对象,例:Java引用类型静态变量
- 方法区中常量引用对象,例:字符串常量池中引用的对象
- 本地方法栈中JNI引用的对象
- Java虚拟机内部引用,例:基本类型对应的Class对象,一些常驻的异常对象
- 所有被同步锁持有的对象
- 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。
-
对象什么时候进入老年代?
- 经过几轮 yung GC仍然存活 ,或者触发了动态年龄判读 默认是15
- 存活对象 在S区放不下,都会让对象进入老年代 (空间担保机制)
-
G1 垃圾收集器了解么?
G1垃圾收集器的设计目标是在停顿时间可控的情况下,最大化系统吞吐量,它旨在提供更可控、更高效的垃圾回收性能。
以下是G1垃圾收集器的一些特点和工作原理:
a). 区域化内存布局:G1收集器将堆内存划分为多个大小相等的区域(region)。每个区域可以是Eden区、Survivor区或Old 区。这种内存布局有助于提高垃圾收集的效率。
b). 并行与并发 : G1收集器使用并行和并发的方式执行垃圾回收操作。它通过并行处理来加快标记和复制阶段的速度,同时利用并发处理来减少垃圾回收对应应用程序的停顿时间。
c).垃圾优先策略: G1收集器使用Garbage-First策略来确定优先处理哪些区域中的垃圾。它会根据区域中的垃圾数量、回收成本等因素来选择下一个要回收的区域,以最大程度地提高垃圾回收的效率。
d).混合回收: G1收集器执行混合回收,即同时处理新生代和老年代的垃圾回收。相比于传统的的分代式回收,它可以均衡地处理整个堆内存,避免长时间的FullGC暂停。
e).可预测的停顿时间: G1收集器使用一种停顿预测模型的机制,通过控制每次垃圾回收的时间目标来实现可预测的停顿时间。开发人员可以通过设置最大停顿时间来控制G1收集器的行