自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 jvm:jvm GC日志解析:G1日志解析

1、背景简介1.1、应用背景介绍1)业务特点:流量高峰都集中在白天,凌晨流量很低。2)应用特点:对外提供了很多核心业务接口,早6点之后,流量逐渐增加。凌晨会通过自动化调度,跑一些数据处理任务,主要都是核心业务数据的缓存预热【从DB(mysql/es)读取,写入到redis】。1.2、jdk版本(openjdk)由于oracle声明将针对企业用户对于JDK 8 u191之后的版本需要付费购买商业许可。所以公司统一都切换到了openjdk,目前应用的版本是:openjdk 1.8.0_272-

2021-12-06 12:09:33 9692 2

原创 JDK8:java线程池源码解析:ThreadPoolExecutor源码,execute方法、addWorker方法解析

一、概述线程池的作用不用太多说了,线程池会按照一定的规则,创建和维护一定数量的线程,这些线程可以被循环利用来处理用户提交的任务。对比不使用线程池的方式,节省了频繁的创建和销毁线程带来的性能开销。二、几个比较重要的概念1. 工作线程(worker)指的是当前线程池用于处理任务的worker对象,每个worker对象内部都持有一个thread对象实例。2. 任务调用方要执行的业务逻辑,一般应该是个Callable或者Runnable的实现。3. 任务队列线程池内部维护了一个队列用来存储待处理的任

2021-03-21 14:51:20 1163 1

原创 elasticsearch(es)在用户画像业务上的应用【elasticsearch(es)性能调优】

1、关于用户画像用户画像是以用户为中心,从不同角度抽取信息,抽象成标签。这些标签一般都会很多,针对不同的业务需求、应用场景会刻画不同的标签。可以通过标签来圈选适合的人群,来进行精准投放。广告系统、活动营销、内容推荐都可以是基于用户画像的应用。2、标签到底能有多少这个和业务体量、业务流程、产品形态都有密切关系。互联网行业的用户规模往往千万乃至上亿,那么可能各区域、各行业、各阶层、各年龄段都能覆盖,用户的天然属性就可以抽象的维度就会很多。再加上和业务相关的各种属性,比如用户的浏览行为、购买行为、售后行为

2020-12-24 14:19:17 5159 4

原创 multipart/form-data与httpclient文件上传

写在前面:本文讨论的内容都是基于java相关技术栈。文件上传无论是在传统的基于html的web系统开发,还是目前主流的移动app开发,都是一个比较常见的功能需求。例如:web oa系统,可能会涉及到各种文档、合同、档案文件的上传。移动app的开发可能会涉及到用户头像、图片动态、语音动态、视频动态等多媒体文件的上传。但是传统的html web文件上传和移动app开发中的文件上传的技术实现还是有很大的差异的。本文重点讨论的是httpclient方式进行文件上传,但并不是只贴实现代码,而是希望通过循序渐进的方

2020-10-08 21:49:44 4806 2

原创 对象池(连接池):连接池参数、commons-pool2、 GenericObjectPool常用参数详解

为什么会有对象池在实际的应用工程当中,存在一些被频繁使用的、创建或者销毁比较耗时、持有的资源也比较昂贵的一些对象。比如:数据库连接对象、线程对象。所以如果能够通过一种方式,把这类对象统一管理,让这类对象可以被循环利用的话,就可以减少很多系统开销(内存、CPU、IO等),极大的提升应用性能。Apache Commons PoolApache Commons Pool就是一个对象池的框架,他提供了一整套用于实现对象池化的API,以及若干种各具特色的对象池实现。Apache Commons Pool是

2020-09-06 14:47:44 3557

原创 对象池(连接池):commons-pool2源码解析:GenericObjectPool的invalidateObject方法解析

为什么会有对象池在实际的应用工程当中,存在一些被频繁使用的、创建或者销毁比较耗时、持有的资源也比较昂贵的一些对象。比如:数据库连接对象、线程对象。所以如果能够通过一种方式,把这类对象统一管理,让这类对象可以被循环利用的话,就可以减少很多系统开销(内存、CPU、IO等),极大的提升应用性能。Apache Commons PoolApache Commons Pool就是一个对象池的框架,他提供了一整套用于实现对象池化的API,以及若干种各具特色的对象池实现。Apache Commons Pool是很多连

2020-08-13 22:56:29 1606 2

原创 对象池(连接池):commons-pool2源码解析:GenericObjectPool的returnObject方法解析

为什么会有对象池在实际的应用工程当中,存在一些被频繁使用的、创建或者销毁比较耗时、持有的资源也比较昂贵的一些对象。比如:数据库连接对象、线程对象。所以如果能够通过一种方式,把这类对象统一管理,让这类对象可以被循环利用的话,就可以减少很多系统开销(内存、CPU、IO等),极大的提升应用性能。Apache Commons PoolApache Commons Pool就是一个对象池的框架,他提供了一整套用于实现对象池化的API,以及若干种各具特色的对象池实现。Apache Commons Pool是很多连

2020-08-06 23:12:16 2633

原创 对象池(连接池):commons-pool2源码解析:GenericObjectPool的addObject、create方法解析

为什么会有对象池在实际的应用工程当中,存在一些被频繁使用的、创建或者销毁比较耗时、持有的资源也比较昂贵的一些对象。比如:数据库连接对象、线程对象。所以如果能够通过一种方式,把这类对象统一管理,让这类对象可以被循环利用的话,就可以减少很多系统开销(内存、CPU、IO等),极大的提升应用性能。Apache Commons PoolApache Commons Pool就是一个对象池的框架,他提供了一整套用于实现对象池化的API,以及若干种各具特色的对象池实现。Apache Commons Pool是很多连

2020-08-02 18:59:25 1331 2

原创 对象池(连接池):commons-pool2源码解析:GenericObjectPool的startEvictor、Evictor、evict解析

在之前的文章中分析过GenericObjectPool的构造方法(参见:https://blog.csdn.net/weixin_42340670/article/details/107300577),在构造方法内部逻辑的最后调用了startEvictor方法。这个方法的作用是在构造完对象池后,启动回收器来监控回收空闲对象。startEvictor定义在GenericObjectPool的父类BaseGenericObjectPool(抽象)类中,我们先看一下这个方法的源码BaseGenericObjec

2020-07-26 13:35:15 1198

原创 springboot、微服务调用、json中文乱码问题排查

背景公司是采用微服务架构,服务即按照业务方向竖向拆分,同时同一个业务方向还按照业务层次横向拆分。其中有三个服务之间的关系如下图:A-service-1服务是A业务团队的一个比较基础的底层服务。基于springboot的2.1.5.RELEASE版本。提供了http形式的接口queryXXX提供了dubbo形式的其他接口A-service-2服务是A业务团队的一个相对上层的服务,基于springboot的2.1.5.RELEASE版本。依赖A-service-1的queryXXX接口,通过

2020-07-18 19:36:48 4408 3

原创 对象池(连接池):commons-pool2源码解析:GenericObjectPool的继承结构、构造方法

概述GenericObjectPool是apache commons pool(源码分析基于commons pool2)框架中的一个非常重要的类。解析GenericObjectPool就有必要先了解一下apache commons pool。apache commons pool(2)apache commons pool框架是一个对象池框架,提供了非常通用的对象池的api以及实现。业务开发中非常常用的连接池,无论是数据库连接池、redis连接池、http连接池等,都可以基于commons pool来

2020-07-12 16:05:02 1847

原创 对象池(连接池):commons-pool2源码解析:GenericObjectPool的abandonedConfig属性、removeAbandoned方法

在解析borrowObject方法时,方法内部最开始的有一小段逻辑如下AbandonedConfig ac = this.abandonedConfig;if (ac != null && ac.getRemoveAbandonedOnBorrow() && (getNumIdle() < 2) && (getNumActive() > getMaxTotal() - 3) ) { removeAband

2020-07-05 12:00:47 3245

原创 对象池(连接池):commons-pool2源码解析:GenericObjectPool的borrowObject方法

Apache Commons Pool库提供了一整套用于实现对象池化的API,以及若干种各具特色的对象池实现。commons-pool2可认为完全不同于commons-pool,里面大部分核心逻辑实现都是完全不同的实现代码。Apache Commons Pool是很多连接池实现的基础,比如DBCP连接池、Jedis连接池等。borrowObject方法的作用,就是从池中获取到一个对象,注意此处没有说是获取一个连接,连接池只是对象池最广泛、同时也最贴近工程使用的一个案例。秉着解析源码先解析注释、先解析接

2020-06-20 19:56:27 3891 1

原创 java io里的BufferedInputStream为什么性能高

java io流的分类从读写角度拆分读取流(InputStream、Reader的子类)写入流(OutputStream、Writer的子类)按操作数据类型可分为字节流:所有InputStream、OutputStream的子类都是字节进行操作。字符流:所有Reader、Writer的子类都是针对字符进行操作。按处理类型可分为终端流(节点流):个人理解,觉得终端流更形象贴切一些。如果某个流是直接和磁盘、内存、网络等物理终端联通来进行读写操作的,这种流就可以称为终端流或者

2020-05-23 17:36:22 1976 4

原创 mysql异常在spring、mybatis里如何流转的

mysql异常在spring、mybatis里如何流转的我们首先还是来看下两种不同异常的堆栈的概要信息,来总结一些类同和差异。unknown thread id异常片段 org.springframework.jdbc.UncategorizedSQLException:### Error updating database. Cause: java.sql.SQLException: Unknown thread id: 64278282### The error may involve

2020-05-17 11:56:35 1196 1

原创 ClassLoader中那些傻傻分不清的概念

ClassLoader中那些傻傻分不清的概念ClassLoader有几种根加载器你的java程序想要运行,就必须有一个运行环境,这个运行环境既包括底层的jvm支持,还包括基础的jre类库支持。那么这些基础的jre类本省也是java的class,所以这些class的加载就是由native代码实现的bootstrap class loader来加载的。根加载器主要加载的是%JAVA_HOME%...

2020-04-25 20:16:44 281

原创 记一次 【Unknown thread id: XXX】 的排查

背景线上一个服务偶尔会产生【Unknown thread id: XXX】异常异常堆栈org.springframework.jdbc.UncategorizedSQLException: ### Error updating database. Cause: java.sql.SQLException: Unknown thread id: 64278282### The error...

2019-03-15 23:58:10 19602 13

原创 JDK8:HashMap源码解析:remove方法、removeNode方法

一、概述在HashMap中如果要根据key删除这个key对应的键值对,需要调用remove(key)方法,该方法将会根据查找到匹配的键值对,将其从HashMap中删除,并且返回键值对的值。二、方法解析我们先来看remove方法/*** 从HashMap中删除掉指定key对应的键值对,并返回被删除的键值对的值* 如果返回空,说明key可能不存在,也可能key对应的值就是null...

2018-07-20 23:24:56 4134

原创 JDK8:HashMap源码解析:get方法、containsKey方法、getNode方法

一、概述HashMap存储的键值对,用put(K,V)方法来存储,用get(K)方法来获取V,用containsKey(K)方法来检查K是否存在。可先参见:put方法解析 来了解键值对的存储原理,再来看get方法就很容易了。二、方法解析/*** 获取key对应的值,如果找不到则返回null* 但是如果返回null并不意味着就没有找到,也可能key对应的值就是null,因为Hash...

2018-06-22 23:41:10 4348

原创 JDK8:HashMap源码解析:TreeNode类的find方法

一、概述当我们向HashMap里put一个键值对的时候,需要检测键是否已经存在,如果存在需要替换值,如果不存在需要添加。当要添加的键产生了hash碰撞,并且碰撞位置上已经是一个树结构时,那么就需要检查该键是否存在于该树上,此时调用find来查找该键对应的节点对象。如果找到了就替换该节点的值,如果未找到就会向树上添加一个新的节点。二、源码解析/*** 这个方法是TreeNode类的一...

2018-06-20 23:06:00 1978 4

原创 JDK8:HashMap源码解析:comparableClassFor、compareComparables、tieBreakOrder方法

一、概述在之前的文章里已经分析过,在发生hash碰撞(多个key的hash值相同)的时候,hashMap首先会采用链表进行存储,当链表节点数量达到一定阈值(8)会将链表上的节点再组织成一棵红黑树。红黑树是一种二叉树,每个父节点可以由左右两个节点。当put一个新元素时,如果该元素键的hash值小于当前节点的hash值的时候,就会作为当前节点的左节点;hash值大于当前节点hash值得时候作为...

2018-06-13 00:25:35 2523 4

原创 JDK8:HashMap源码解析:TreeNode类的putTreeVal方法

一、概述我们都知道,目前HashMap是采用数组+链表+红黑树的方式来存储和组织数据的。在put数据的时候,根据键的hash值寻址到具体数组位置,如果不存在hash碰撞,那么这个位置就只存储这么一个键值对。参见:put方法分析如果两个key的hash值相同,那么对应数组位置上就需要用链表的方式将这两个数据组织起来,当同一个位置上链表中的元素达到8个的时候,就会再将这些元素构建成一个红黑...

2018-06-09 18:31:48 3816 2

原创 JDK8:HashMap源码解析:hash方法

一、概述我们知道在HashMap中,一个键值对存储在HashMap内部数据的哪个位置上和K的hashCode值有关,这也是因为HashMap的hash算法要基于hashCode值来进行。这里要注意区分三个概念:hashCode值、hash值、hash方法、数组下标hashCode值:是KV对中的K对象的hashCode方法的返回值(若没有重写则默认用Object类的hashCode方法...

2018-06-05 01:20:08 4432 9

原创 JDK8:HashMap源码解析:TreeNode类的moveRootToFront方法

一、概述TreeNode在增加或删除节点后,都需要对整个树重新进行平衡,平衡之后的根节点也许就会发生变化,此时为了保证:如果HashMap元素数组根据下标取得的元素是一个TreeNode类型,那么这个TreeNode节点一定要是这颗树的根节点,同时也要是整个链表的首节点。二、方法解析/** * 把红黑树的根节点设为 其所在的数组槽 的第一个元素 * 首先明确:TreeNode既...

2018-06-03 13:07:22 2851 5

原创 JDK8:HashMap源码解析:TreeNode类的balanceInsertion方法

一、概述balanceInsertion指的是红黑树的插入平衡算法,当树结构中新插入了一个节点后,要对树进行重新的结构化,以保证该树始终维持红黑树的特性。关于红黑树的特性: 性质1. 节点是红色或黑色。性质2. 根节点是黑色。性质3 每个叶节点(NIL节点,空节点)是黑色的。性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)...

2018-06-02 20:28:00 4291 14

原创 JDK8:HashMap源码解析:TreeNode类的treeify方法

一、概述treeify方法是TreeNode类的一个实例方法,通过TreeNode对象调用,实现该对象打头的链表转换为树结构。 二、方法解析/** * 参数为HashMap的元素数组 */final void treeify(Node&lt;K,V&gt;[] tab) { TreeNode&lt;K,V&gt; root = null; // 定义树的根节点 ...

2018-06-01 00:52:21 5919

原创 JDK8:HashMap源码解析:replacementTreeNode方法、TreeNode类

一、概述 HashMap中每一个键值对都是以一个HashMap.Node&lt;K,V&gt;对象实例进行存储的,当不同的键对应的多个键值对路由到元素数组的同一个位置时,这多个键值对对应的Node对象之间会以链表的方式组织起来。这是默认的组织方式。 当我们恰好要根据key寻找一个在链表上的对象的时候,就涉及到遍历链表,逐个调用key对象的equals方法来比对我们要查找...

2018-05-30 23:24:24 1229 2

原创 JDK8:HashMap源码解析:treeifyBin方法

一、概述treeifyBin方法,应该可以解释为:把容器里的元素变成树结构。当HashMap的内部元素数组中某个位置上存在多个hash值相同的键值对,这些Node已经形成了一个链表,当该链表的长度大于等于9(为什么是9?TREEIFY_THRESHOLD默认值为8呀?详见put方法解析:https://blog.csdn.net/weixin_42340670/article/details/...

2018-05-30 00:40:14 10281 22

原创 JDK8:HashMap源码解析:newNode方法、Node类

一、概述在Map中存储的每一个键值对都是以一个Map.Entry&lt;K,V&gt;的实现对象存储的,Map.Entry是一个接口,不能实例化,所以Map的不同实现类,存储键值对的方式也会有所不同,只要这个键值对的类实现了Map.Entry接口即可。在HashMap中键值对的存储方式有两种:其中一种是我们比较熟知的链表存储结构,也就是以HashMap.Node&lt;K,V&gt;类...

2018-05-29 23:20:01 4646

原创 JDK8:HashMap源码解析:resize方法

一、概述HashMap的resize方法的作用:在向HashMap里put元素的时候,HashMap基于扩容规则发现需要扩容的时候会调用该方法来进行扩容。二、方法解析final Node<K,V>[] resize() { Node<K,V>[] oldTab = table; //当前所有元素所在的数组,称为老的元素数组 ...

2018-05-29 23:12:34 4567 9

原创 JDK8:HashMap源码解析:put方法

一、概述Map的put方法接受两个参数,key和value,该方法用于存储键值对。HashMap的put方法只有一行代码: return putVal(hash(key), key, value, false, true); //参见:hash方法解析hash方法解析 可知put方法是一个方便用户使用的快捷方式,具体逻辑都是在putVal方法中实现的,我们就针对putVa...

2018-05-29 22:54:56 3112 5

空空如也

空空如也

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

TA关注的人

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