自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(51)
  • 收藏
  • 关注

原创 【JVM系列】后端编译优化

后端编译器优化主要指的运行时的即时编译器方法内联最重要的优化技术之一:方法内联。优点一是去除方法调用的成本(如查找方法版本、建立栈帧等)二是为其他优化建立良好的基础。方法内联膨胀之后可以便于在更大范围上进行后续的优化手段,可以获取更好的优化效果。实现内联与虚方法之间会产生“矛盾”。大多数的Java方法都无法进行内联,只有使用invokespecial指令调用的私有方法、实例构造器、父类方法和使用invokestatic指令调用的静态方法才会在编译期进行解析,其他的Java方法调用

2020-10-27 09:52:23 214 3

原创 【JVM系列】前端编译与语法糖

编译与优化前端编译器Javac从Javac代码的总体结构来看,编译过程大致可以分为1个准备过程和3个处理过程,它们分别如下所示。准备过程:初始化插入式注解处理器。解析与填充符号表过程,包括:词法、语法分析。将源代码的字符流转变为标记集合,构造出抽象语法树。填充符号表。产生符号地址和符号信息。插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段分析与字节码生成过程,包括:标注检查。对语法的静态信息进行检查。数据流及控制流分析。对程序动态运行过程进行检查。解语法

2020-10-27 00:12:11 199 5

原创 【JVM系列】方法执行指令详解

方法执行分类jvm 有 5 条调用方法的字节码指令invokestatic。用于调用静态方法。invokespecial。用于调用实例构造器<init>()方法、私有方法和父类中的方法。invokevirtual。用于调用所有的虚方法。invokeinterface。用于调用接口方法,会在运行时再确定一个实现该接口的对象。invokedynamic。先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法。可以分为三类(说到底是因为方法的多态性)invokesta

2020-10-27 00:12:00 1646 2

原创 【JVM系列】类加载器详解(JDK9+)

模块化如何向前兼容具名模块(Named Module)具名模块也称为应用模块(Application Module),通常在模块根目录下有 module-info.java 文件的话,那么该模块就称为具名模块,我们编写的模块一般都属于这种类型。无名模块(Unnamed Module):不分模块的 jar 包,放到 不分模块的路径(即这个项目类路径下)无名模块指的就是不包含 module-info.java 的 jar 包,通常这些 jar 包都是 Java 9 之前构建的。无名模块可以读取

2020-10-27 00:11:48 4768 7

原创 【JVM系列】类加载过程

加载过程阶段一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)七个阶段。其中验证、准备、解析三个部分统称为连接(Linking)。顺序加载、验证、准备、初始化和卸载这五个阶段的开始顺序是确定的,类型的加载过程必须按照这种顺序按部就班地开始,而解析阶段则

2020-10-27 00:11:33 154

原创 【JVM系列】类加载时机

加载时机引用关系主动引用(指会触发类加载,有且只有下面6种)遇到new、getstatic、putstatic或invokestatic这四条字节码指令时,如果类型没有进行过初始化,则需要先触发其初始化阶段。使用new关键字实例化对象的时候。读取或设置一个类型的静态字段的时候(被final修饰、已在编译期把结果放入常量池的静态字段除外)。调用一个类型的静态方法的时候。使用java.lang.reflect包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需要先触发其初始化。

2020-10-27 00:11:21 107 2

原创 【JVM系列】类加载时机

调优问题无非就是两种抛出异常:如果抛出 oom,怎么解决没抛出异常:如果没抛出异常,只是 gc 停顿时间过长,或者频率高,或者影响到了系统吞吐量,怎么解决分析工具进程查询工具jpsjps 主要用来输出JVM中运行的进程状态信息jps [options] [hostid]options-q:不输出类名、Jar名 和传入main方法的参数-m:输出传入main方法的参数-l:输出main类或Jar的全限名-v:输出传入JVM的参数hostid如果不指定h

2020-10-27 00:07:17 1280 1

原创 【JVM系列】故障处理工具与六种OOM

参数分代通用参数补充说明-XX:+UseAdaptiveSizePolicy:如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到-XX:MaxTenuringThreshold中要求的年龄。-XX:+HandlePromotionFailure:在发生Minor GC之前,虚拟机必须先检查老年代最大可用的连续空间是否大于新生代所有对象总空间如果这个条件成立,那这一次Minor GC可以确保是安全的

2020-10-26 23:53:36 227 3

原创 【JVM系列】无操作Epsilon与回收器参数

无操作Epsilon收集器自动内存管理子系统Epsilon,是一款以不能够进行垃圾收集为“卖点”的垃圾收集器,被形容成一个无操作的收集器(A No-Op Garbage Collector)。而事实上只要Java虚拟机能够工作,垃圾收集器便不可能是真正“无操作”的。原因是“垃圾收集器”这个名字并不能形容它全部的职责,更贴切的名字应该是“自动内存管理子系统”。一个垃圾收集器除了垃圾收集这个本职工作之外,它还要负责堆的管理与布局、对象的分配、与解释器的协作、与编译器的协作、与监控子系统协作等职责,其中

2020-10-26 23:50:42 272

原创 【JVM系列】低延迟回收器 ZGC

ZGC收集器ZGC主要特征基于Region内存布局的,(暂时)不设分代的,使用了读屏障、染色指针和内存多重映射等技术来实现可并发的标记-整理算法的,以低延迟为首要目标的一款垃圾收集器。内存布局(ZGC的Region有大、中、小三类容量)小型Region(Small Region):容量固定为2MB,用于放置小于256KB的小对象。中型Region(Medium Region):容量固定为32MB,用于放置大于等于256KB但小于4MB的对象。大型Region

2020-10-26 23:50:11 207

原创 【JVM系列】低延迟回收器 Shenandoah

Shenandoah收集器比起G1改进最重要的当然是支持并发的整理算法,G1的回收阶段是可以多线程并行的,但却不能与用户线程并发,这点是Shenandoah最核心的功能其次,Shenandoah(目前)是默认不使用分代收集的,换言之,不会有专门的新生代Region或者老年代Region的存在,没有实现分代,并不是说分代对Shenandoah没有价值,这更多是出于性价比的权衡,基于工作量上的考虑而将其放到优先级较低的位置上。最后,Shenandoah摒弃了在G1中耗费大量内存和计算资源去维

2020-10-26 23:50:00 207

原创 【JVM系列】Region 内存布局回收器 G1

G1收集器特点可以面向堆内存任何部分来组成回收集(Collection Set,一般简称CSet)进行回收,衡量标准不再是它属于哪个分代,而是哪块内存中存放的垃圾数量最多,回收收益最大,这就是G1收集器的Mixed GC模式。能够建立起“停顿时间模型”(Pause Prediction Model)的收集器,停顿时间模型的意思是能够支持指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间大概率不超过N毫秒这样的目标,以后会完全取代 CMS(CMS 在 JDK 9 已经过时)。可预测的停顿时

2020-10-26 23:49:34 1363

原创 【JVM系列】经典垃圾回收器

垃圾回收器分类Partial GC:并不收集整个GC堆的模式Young GC:只收集young gen的GC,有 Serial GC 、ParNew GC、Parallel Scavenge GC。Old GC:只收集old gen的GC。只有 CMS GC 是针对老年代的。Mixed GC:收集整个young gen以及部分old gen的GC,即所有分 Region 的收集器,包括 G1、Shenandoah、ZGC。Full GC:收集整个堆,包括young gen、old g

2020-10-26 23:49:19 274

原创 【JVM系列】HotSpot回收算法细节

HotSpot算法细节发起内存回收安全点安全点如何选取数量:其选定的既不能太少以至于让收集器等待时间过长,也不能太过频繁以至于过分增大运行时的内存负荷。位置:安全点位置的选取基本上是以“是否具有让程序长时间执行的特征”为标准进行选定的,因为每条指令执行的时间都非常短暂,程序不太可能因为指令流长度太长这样的原因而长时间执行。“长时间执行”的最明显特征就是指令序列的复用,例如方法调用、循环跳转、异常跳转等都属于指令序列复用,所以只有具有这些功能的指令才会产生安全点。实现方案抢先式中

2020-10-26 23:49:00 161

原创 【JVM系列】垃圾回收判定与算法

垃圾回收原因与算法介绍在 JVM 中,程序计数器、虚拟机栈、本地方法栈 3 个区域随线程而生,随线程而灭,而栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的(尽管在运行期会由即时编译器进行一些优化,但在基于概念模型的讨论里,大体上可以认为是编译期可知的)。因此这几个区域的内存分配和回收都具备确定性,在这几个区域内就不需要过多考虑如何回收的问题,当方法结束或者线程结束时,内存自然就跟随着回收了。而 Java 堆和方法区这两个区域则

2020-10-26 23:48:41 1239 2

原创 【JVM系列】对象详解

对象创建过程1、当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程,2、在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。内存分配划分方式指针碰撞:假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在

2020-10-26 23:48:25 127

原创 【JVM系列】运行时数据区域详解

运行时数据区域程序计数器在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。此内存区域是唯一一个在《Java虚拟机规范》中没有

2020-10-26 23:48:07 192

原创 【JUC源码系列】Fork / Join 框架源码解析

Fork / Join使用ForkJoinTask:我们要使用 ForkJoin 框架,必须首先创建一个 ForkJoin 任务。它提供在任务中执行 fork() 和 join() 操作的机制,通常情况下我们不需要直接继承 ForkJoinTask 类,而只需要继承它的子类,Fork/Join 框架提供了以下两个子类:RecursiveAction:用于没有返回结果的任务。RecursiveTask :用于有返回结果的任务。ForkJoinPool :ForkJoinTask 需要通过 F

2020-10-17 00:05:11 1373 2

原创 【线程池源码系列】ScheduledThreadPoolExecutor 源码解析

ScheduledThreadPoolExecutor虽然 Timer 与 TimerTask 可以实现线程的周期和延迟调度,但是对于定期、周期执行任务的调度策略存在一些缺陷,所以一般都是推荐ScheduledThreadPoolExecutor 来实现构造方法都是利用ThreadLocalExecutor来构造的,但是所使用的阻塞队列变成了 DelayedWorkQueueDelayedWorkQueue 为 ScheduledThreadPoolExecutor 中的内部类,它其实和阻塞队

2020-10-17 00:04:59 227

原创 【线程池源码系列】ThreadPoolExecutor 源码解析(下)

Wokerworker 就是工作线程的 Runnable 参数对象,线程启动后会调用其 run()// 继承 AQS 主要是为了方便线程的中断处理,即不是为了防止有多个线程来争抢什么资源,// 而是因为,如果当前线程在 getTask() 获取到 task ,要执行前会 aquire 独占锁,// 外部要中断这个线程的时候,也会先获得独占锁,那么如果当前线程正在执行某个 task // 外部就会获取失败,反之同理,从而就可以起到个 正在执行任务 和 外部中断 互斥的作用(标识作用)。privat

2020-10-17 00:04:45 134

原创 【线程池源码系列】ThreadPoolExecutor 源码解析(上)

ThreadPoolExecutor属性/** * 高 3 位是 线程池状态 * 后 29 位是 工作线程个数 */private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));private static final int COUNT_BITS = Integer.SIZE - 3;private static final int CAPACITY = (1 << COUNT_BITS) -

2020-10-17 00:04:30 191

原创 【线程池源码系列】 Executor 体系与 Future 体系解析

线程池结构ExecutorExecutor 提供了一种将“任务提交”与“任务执行”分离开来的机制,它仅提供了一个 #execute(Runnable command) 方法,用来执行已经提交的 Runnable 任务。public interface Executor { void execute(Runnable command); }ExcutorServiceExcutorService 拓展了一些方法,为了让提交执行模式更加完善,比如提交任务的:submit、invoke

2020-10-17 00:04:16 263

原创 【阻塞队列源码系列】 LinkedTransferQueue 源码解析

LinkedTransferQueueLinkedTransferQueue是下面三者的集合体LinkedBlockingQueue(支持阻塞,即失败入队,但不再支持获取 Lock 的阻塞了,因为是基于 cas 的)SynchronousQueue(公平模式,实现了 Transfer 接口)ConcurrentLinkedQueue (支持非阻塞,因为传统的阻塞队列都是使用的 Lock,想要 offer 或者 poll 等操作必须先获得 lock,而非阻塞是 直接cas 一次,失败就直接返回,

2020-10-16 23:49:07 328

原创 【阻塞队列源码系列】 SynchronousQueue 源码解析

SynchronousQueue特性SynchronousQueue 没有容量。与其他 BlockingQueue 不同,SynchronousQueue 是一个不存储元素的 BlockingQueue。可以有多个 put ,但每一个put操作必须要等待一个take操作,否则该线程会一直阻塞在 put,反之亦然。因为没有容量,所以对应 peek, contains, clear, isEmpty … 等方法其实是无效的。例如 clear 是不执行任何操作的,contains 始终返回 false,

2020-10-16 23:48:53 1500 2

原创 【阻塞队列源码系列】 DelayQueue 源码解析

DelayQueue一个支持延时获取元素的无界阻塞队列,里面的元素全部都是“可延期”的元素,**列头的元素必须是最先“到期”**的元素,如果列头不出队,其他元素是无法出队的。主要用于两个方面:缓存(清掉缓存中超时的缓存数据)、任务超时处理底层实现是优先队列,在出队时调用了内部优先队列 peek 方法先查询其队首元素,如果到期了才调用优先队列的 poll 让队首出队,否则就阻塞等队首到期,也就是说优先队列中只有前一个元素到期并出队后,后面的元素才能出队。并发安全也是通过 Lock。元素元素必须

2020-10-16 23:48:34 239

原创 【阻塞队列源码系列】 PriorityBlockingQueue 源码解析

PriorityBlockingQueue一个支持优先级的无界阻塞队列。默认情况下元素采用自然顺序升序排序,当然我们也可以通过构造函数来指定Comparator来对元素进行排序。需要注意的是PriorityBlockingQueue不能保证同优先级元素的顺序。底层实现是数组,采用的堆的思想(最小堆),保证数组第零个元素是最小的元素,但是注意,其增加和删除元素的调整方法并非是堆排的调整方法,即不用满足最小堆的堆排所要求的左子节点小于右子节点,只用满足根元素是最小的元素。并发安全也是通过 Lock 保证,

2020-10-16 23:48:19 259

原创 【阻塞队列源码系列】 LinkedBlockingDeque 源码解析

LinkedBlockingDeque实现接口 BlockingDeque,而 BlockingDeque 又继承接口 BlockingQueue ,提供了一系列的以First和Last结尾的方法,如addFirst、addLast、peekFirst、peekLast,为双向操作Queue提供了可能。底层实现就是链表,然后用 Lock 加锁,维护了头节点和尾节点LinkedBlockingQueue 介绍省略属性public class LinkedBlockingDeque<E&gt

2020-10-16 23:48:03 200

原创 【阻塞队列源码系列】 ArrayBlockingQueue 源码解析

ArrayBlockingQueue一个由数组实现的有界阻塞队列,其大小在构造时由构造函数来决定,确认之后就不能再改变了支持对等待的生产者线程和使用者线程进行排序的可选公平策略,但是在默认情况下不保证线程公平的访问,在构造时可以选择公平策略(fair = true),就是说 ReentrantLock 会变成公平锁。公平性通常会降低吞吐量,但是减少了可变性和避免了“不平衡性”。底层实现就是数组,然后用 Lock 加锁,同时维护队头和队尾索引,并且是循环的属性public class Array

2020-10-16 23:47:50 116

原创 【并发容器源码系列】 JDK 1.7 Concurrenthashmap 源码对比

Concurrenthashmap1.8和1.7版本实现原理JDK 1.7: ReentrantLock + Segment + HashEntry 分段锁思想(简单点说就是 Map 的所有槽位并不分布在一个 table 上,而是分布在多个 table 上,每个 table 就是一个分段,并且锁的颗粒度不再是槽位,而是一个分段的 table)hash 槽只有 HashEntry 一种类型,因为不会树化所以没有树相关节点,并且因为是分段锁,锁的是一个包含部分槽位的 table,所以也不会出现扩容和读写同

2020-10-16 23:47:33 149

原创 【并发容器源码系列】 ConcurrentHashMap 存入相关源码解析

putpublic V put(K key, V value) { return putVal(key, value, false);}final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException(); // 计算hash值:(h ^ (h >>> 16)) & HA

2020-10-16 23:47:13 93

原创 【并发容器源码系列】 ConcurrentHashMap 查找相关源码解析

size为了更好地统计size,ConcurrentHashMap提供了 baseCount 、counterCells 两个辅助变量。定义@sun.misc.Contended static final class CounterCell { volatile long value; // 该CounterCell 统计的元素个数 CounterCell(long x) { value = x; } }//ConcurrentHashMap中元素个数,但返回

2020-10-16 23:46:51 220

原创 【并发容器源码系列】 ConcurrentHashMap 结构相关源码解析

ConcurrentHashMaphash 槽节点类型Nodestatic class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; volatile V val; //带有volatile,保证可见性 volatile Node<K,V> next; //下一个节点的指针 Node(int hash, K

2020-10-16 23:46:30 148

原创 【并发容器源码系列】ConcurrentLinkedQueue 源码解析

ConcurrentLinkedQueueNodeprivate static class Node<E> { /** 节点元素域 */ volatile E item; volatile Node<E> next; Node(E item) { UNSAFE.putObject(this, itemOffset, item); } boolean casItem(E c

2020-10-15 01:18:24 186

原创 【并发容器源码系列】 CopyOnWriteArrayList 源码解析

CopyOnWriteArrayListCopyOnWriteList 实现的接口和 ArrayList 完全相同,所以 ArrayList 提供的 api ,CopyOnWriteArrayList 也提供其实说白了就是每次要增、删、改的时候,会创建一个新的 array,并把旧的 array 全部复制过来,操作完后再让 array 指向这个新创建的 array,所以也不存在什么扩容问题,因为每次 add 都要扩容属性/** The lock protecting all mutato

2020-10-15 01:18:00 81

原创 【并发工具源码系列】 Exchanger 源码解析

Exchanger线程之间可以进行元素交换(了解就行了)实际就是 Exchanger 在没有线程竞争的时候,提供了一个 Node 叫 slot 当作交换的中间场地,让你这个线程和另外一个线程把值放在 Node#item 进行交换交换流程是,如果你去交换了,但是 Node 里面没有 item 可以让你交换,那你就把你的 item 用 cas 放到 Node 里面,然后把你这个线程保存在 Node 里面,你挂起就行了,等下一个来交换的话线程,把你的 item 取走,然后把它的 item 放到 Node

2020-10-15 01:04:11 231

原创 【并发工具源码系列】 Semaphore 源码解析

Semaphore限制可以访问某些资源(物理或逻辑的)的线程数目实际上是就是普通共享锁,内部静态类 Sync 继承了 AQS,实现了共享锁的 tryAcquireShared、tryReleaseShared。逻辑就是正常共享锁逻辑,同时还可以实现公平和非公平可以说是 ReentrantLock 的共享版,所以注意要在 finally 里面调用 semaphore.release() 释放锁Sync 抽象类abstract static class Sync extends Ab

2020-10-15 01:03:53 132

原创 【并发工具源码系列】 CountDownLatch 源码解析

CountDownLatch在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待实际上是就是共享锁,内部静态类 Sync 继承了 AQS,实现了共享锁的 tryAcquireShared、tryReleaseShared但是实现是反过来的在 tryAcquireShared 获取同步状态的时候, state > 0 返回 false,state == 0,返回 true,从而达到如果 count 没减到零,那么调用 await 的线程全部进 CLH 去挂起在 tryRel

2020-10-15 01:03:42 147

原创 【并发工具源码系列】CyclicBarrier 源码解析

CyclicBarrier它允许一组线程互相等待,直到到达某个公共屏障点,才会进行后续任务内部是使用重入锁 ReentrantLock 及其 Condition 。因为只有一个 await 操作,不像 countDownLatch 和 Semaphore 有释放操作,所以没法调用 release,那么就用 conditon 来阻塞,不用 CLH 队列属性/** * Generation 是 CyclicBarrier 内部静态类,描述了 CyclicBarrier 的更新换代。在Cyclic

2020-10-15 01:03:30 181

原创 【AQS 源码系列】AQS 之 Condition 源码解析

ConditionCondition 接口// ========== 阻塞 ==========// 造成当前线程在接到信号或被中断之前一直处于等待状态。void await() throws InterruptedException; // 造成当前线程在接到信号之前一直处于等待状态。【注意:该方法对中断不敏感】。void awaitUninterruptibly(); // 造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。// 返回值表示剩余时间,如果在`na

2020-10-15 01:01:46 229

原创 【AQS 源码系列】AQS 之 ReentrantReadWriteLock 源码解析(下)

Sync 实现类NonfairSyncwriterShouldBlock@Overridefinal boolean writerShouldBlock() { // 非公平的写锁获取前不用判断是不是要等待前面的节点 return false; // writers can always barge}readerShouldBlock@Overridefinal boolean readerShouldBlock() { // 判断是否当前写锁已经被获取

2020-10-15 01:01:00 142

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除