深入理解jvm虚拟机-常用垃圾回收器解读
概览 CMS(Concurrent Mark Sweep)垃圾回收器 采用标记清除算法 分为四阶段 初始标记,用户线程需要停顿 并发标记,用户线程不需要停顿 重新标记,使用增量更新,用户线程不需要停顿 并发清除,用户线程不需要停顿 缺点: 占用资源过高,降低程序吞吐量 浮动垃圾无法清理,需要等到下一次再处理,这就导致了cms不能等到老年代快要占满了才去进行垃圾回收,得需要预留一些空间给浮动垃圾,如果在并发清理期间无法分配内存至新的对象,那么会导致并发失败,此时虚拟机启用serial old垃圾回收进行处理 内存碎片过多 Garbage First垃圾回收器 面向局部回收的收集思路和基于Region的内存布局形式,在JDK9中,G1取代了Parallel Scavenge组合,G1的开创基于region的堆内存布局是他能够实现这个目标的关键,G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分成为多个大小相等的独立区域,每一个region都可以根据需要,扮演新生代的Eden区、Survivor区、或者老年代空间,收集器可以根据扮演不同角色的r ...
深入理解jvm虚拟机-Hotspot虚拟机垃圾回收算法细节实现
GC流程 一般虚拟机要开始GC的话需要进行GC Root的寻找和扫描,在找到GC Root之后进行遍历,进行可达性分析,标记然后清除 GC Root枚举实现 基于GC Root虚拟机要进行垃圾回收,但垃圾回收的第一个拦路虎出现了,如何快速找到GC Root?虚拟机它在开始垃圾回收的时候面对的是一块内存地址,如何从内存地址中快速找到GC Root的起始,这是我们要解决的议题,针对这个问题,虚拟机采用了一个OopMap的数据结构去记录GC Root的起始位置,这样虚拟机利用这个数据结构就可以快速找到GC Root并进行遍历 跨代引用? 在垃圾回收中,分Minor GC和Full GC,也就是新生代GC和老年代GC,如果程序中存在着老年代中的对象引用了新生代对象的情况,那么在Minor GC的过程中为了寻找GC Root就会去扫描整个老年代的内存区域,这样代价是巨大的,为了解决这种跨代引用的问题,虚拟机同样采用了一个叫记忆集的数据结构去记录老年代中的哪块内存存在着跨代引用的情况,那么即使在出现跨代引用的情况之后,Minor GC也不需要去扫描整个老年代的内存区域,记忆集的实现在不同的虚拟机 ...
深入理解jvm虚拟机-java内存区域与内存溢出异常
Jvm内存区域划分 新建对象流程 Java程序是如何运行起来的 对象的内存布局 jdk6与jdk7的不同 12345678class Test { public static void main(String[] args) { String str1 = new StringBuilder("hello").append("world").toString(); System.out.println(str1.intern() == str1) // false String str2 = new StringBuilder("ja").append("va").toString(); System.out.println(str2.intern() == str2) // true sun.misc.Version }} 1intern() 去查看当前字符串常量池里面是否有这个字符串的变量 ...
深入理解jvm虚拟机-垃圾回收器与内存分配策略
什么是垃圾回收?(Garbage Collection) 对于高级语言动态内存分配而言,一些对象随着程序线程的消亡不再进行使用,为了使程序效率更加高效,特有垃圾回收的技术来保证程序运行状态下能够健康的使用宿主机内存 如何判断对象已死,需要回收? 引用计数法:对于一个对象而言,在对象中添加一个计数器,如果有人引用这个对象,计数器加一,反之,计数器减一,当计数器的值为0的时候,表示对象已经无人在使用,需要回收,但引用计数法也有缺点: 无法解决循环引用 有更多的不确定性 可达性分析算法:基本思路通过一系列称之为“GC Root”的节点开始向下搜索,如果对象到“GC Root”之间路不通,那么表示这个对象需要被回收,用数据结构的思想去解释,“GC Root”与对象之间形成了有向无环图,如果从“GC Root”去进行遍历,无法到达对象节点,那么表示这个对象已经无人再去使用,可以被定义为“GC Root”的路径有以下几点: 虚拟机栈帧中本地变量表引用的对象,例如当前方法中的参数、局部变量、临时变量 方法区中类属性静态属性引用的对象,例如Java类的引用类型静态变量 方法区中常量引用的对象 ...
2021年终总结
2021.12.31 2021年终总结 在2021年的最后一天,耳机里播放着周杰伦的说好不哭,我写下了这篇年终总结。 2021年,对于全世界来说,是多灾多难的一年,疫情当道,洪灾泛滥,火山爆发,地震频繁,全世界都在经受着自然的考验;对我而言,2021年是自我治愈、自我救赎的一个年头,伴随着我的坏情绪,2021年在今日走到了尽头,画上一个圆满的句号。 今天是我跟前任分手的554天,也是我跟前任彻底失去联系的308天,说实话我并没有彻底从上一段感情中脱身而出,现在房间里还放满了充满着无数回忆的物件,不经意间还是会喊出前任的名字,认认真真忘掉一个人真的很难,我也在努力开始一段新的生活,可是星座的影响让我对于情感充满了感性,明知道已经不可能会有下文,可是还在无谓的幻想,原地踏步,可以说,从情感上,2021年我是失败的,也是无奈的一年。 2021年3月份的生日是天津可爱的同事陪我一起度过,有同组的大哥大姐,有不同组的兄弟姐妹,在天津的生活普通且安逸,每天不用加班,也不用打卡,天津固有的慢节奏让人不自觉地就会脚步放慢,享受这独有的生活气息: 在过完生日的几天之后,同在天津上学的大学好友也来找我 ...
浅析SparkContext中的组件与创建流程
前言 在Spark框架中,应用程序的提交离不开Spark Driver,而Spark Driver的初始化始终围绕SparkContext的初始化,可以说SparkContext是Spark程序的发动机引擎,有了它程序才能跑起来,在spark-core中,SparkContext重中之重,它提供了很多能力,比如生成RDD,比如生成广播变量等,所以学习SparkContext的组件和启动流程有助于剖析整个Spark内核的架构。 SparkContext组件概览 在SparkContext中包含了整个框架中很重要的几部分: SparkEnv:Spark的运行环境,Executor会依赖它去执行分配的task,不光Executor中有,同时为了保证本地模式任务也能跑起来,Driver中也有 SparkUI:Spark作业的监控页面,底层并没有采用前端技术,纯后端实现,用以对当前SparkJob的监控和调优,可以从页面观察到目前的Executor的jvm信息,每个job的stage划分和task划分,同时还可以观察到每个task处理的数据,用以发现数据是否倾斜 DAGScheduler:DA ...
数据结构系列30-B树
前言 在面试中,面试官很容易问到B树这种数据结构,要去熟练的掌握这个数据结构还是有一定的难度,为了提升自身的技术深度,我特地花了一定的时间梳理和总结一下B树的全部概念与操作。 B树的概念 B树是一种多路平衡查找树,不同于二叉平衡树,他不只是有两个分支,而是有多个分支,一棵m阶B树(balanced tree of order m)是一棵平衡的m路搜索树,B树用于磁盘寻址,它是一种高效的查找算法。 B树的性质 根节点至少有2个子女 每个非根节点所包含的关键字个数x满足以下关系:⌈m/2⌉−1⩽x⩽m−1\lceil m/2 \rceil - 1 \leqslant x \leqslant m - 1⌈m/2⌉−1⩽x⩽m−1 所有叶子结点都在同一层 除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树个数 k 满足:⌈m/2⌉⩽k⩽m\lceil m/2 \rceil \leqslant k \leqslant m⌈m/2⌉⩽k⩽m B树数据结构描述 一个B树结点包含了以下关键信息: 关键字数量 关键字数组指针 孩子数组指针 父亲结点指针 ...
SparkConf源码解读
在新启动一个spark作业的同时,我们需要去创建一个上下文对象,不论是spark-sql,还是spark-core亦或是spark-streaming,每一个上下文都会依赖一个SparkConf对象,在spark作业调优的过程中,SparkConf这个对象起了至关重要的作用。 1. 核心参数在SparkConf对象中如何保存: 1private val settings = new ConcurrentHashMap[String, String]() 所有配置项都保存在对应的ConcurrentHashMap当中,而且配置的key和value都是string类型的变量 2. 核心方法set 12345678910111213private[spark] def set(key: String, value: String, silent: Boolean): SparkConf = { if (key == null) { throw new NullPointerException("null key") } ...
Spark源码解读之spark-shell
依稀记得在刚开始学习spark框架的时候,第一次接触的就是spark-shell这个东西,但背后它究竟做了什么样的工作,今天来一探究竟: 打开spark-shell,实际上它是一个shell脚本,里面最核心的内容如下: 12345678910111213141516function main() { if $cygwin; then # Workaround for issue involving JLine and Cygwin # (see http://sourceforge.net/p/jline/bugs/40/). # If you're using the Mintty terminal emulator in Cygwin, may need to set the # "Backspace sends ^H" setting in "Keys" section of the Mintty options # (see https://github.com/sbt/sbt/is ...
数据结构系列29-二分查找
数据结构系列29 - 二分查找 - C语言实现 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596/************************************************************************** File Name: BinarySearch.c* Author: TyrantLucifer* E-mail: TyrantLucifer@gmail.com* Blog: https://tyrantlucifer.com* Created Time: Sun 14 Nov 2021 12:45:42 PM CST *********************************************** ...