Skip to content

Commit ec50fb1

Browse files
author
hekuangsheng
committed
Add desig file
1 parent d79e85e commit ec50fb1

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

meituan-backend/meituan-backend-pdf_abstract.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,82 @@
9595
jcmd 272662 VM.native_memory detail
9696
如果 total 中的 committed 和 top 中的 RES 相差不大,则应为主动申请的堆外内存
9797
未释放造成的,如果相差较大,则基本可以确定是 JNI 调用造成的
98+
99+
原因一:主动申请未释放: NIO 和 Netty 都会取 -XX:MaxDirectMemorySize 配置的值,来限制申请的堆外内存的大小
100+
原因二:通过 JNI 调用的 Native Code 申请的内存未释放: 通过 Google perftools + Btrace 等工具,帮助我们分析
101+
首先可以使用 NMT + jcmd 分析泄漏的堆外内存是哪里申请,确定原因后,使用不同的手段,进行原因定位。
102+
103+
JNI 引发的 GC 问题: 添加 -XX+PrintJNIGCStalls 参数,可以打印出发生 JNI 调用时的线程,
104+
禁用偏向锁:偏向锁在只有一个线程使用到该锁的时候效率很高,但是在竞争激烈情况会升级成轻量级锁,此时就需要先消除偏向锁,这个过程是STW 的。
105+
```
106+
### ZGC(The Z Garbage Collector)是 JDK 11 中推出的一款低延迟垃圾回收器
107+
```
108+
CMS 新生代的 Young GC、G1 和 ZGC 都基于标记 - 复制算法
109+
标记阶段停顿分析
110+
初始标记阶段:初始标记阶段是指从 GC Roots 出发标记全部直接子节点的过程,该阶段是 STW 的 (就遍历一层,快)
111+
并发标记阶段:并发标记阶段是指从 GC Roots 开始对堆中对象进行可达性分析,找出存活对象 (可达性分析,并发,慢)
112+
再标记阶段:重新标记那些在并发标记阶段发生变化的对象。该阶段是 STW 的 (???)
113+
114+
清理阶段停顿分析
115+
清理阶段清点出有存活对象的分区和没有存活对象的分区,该阶段不会清理垃圾对象,也不会执行存活对象的复制。该阶段是 STW 的
116+
复制阶段停顿分析
117+
的转移阶段需要分配新内存和复制对象的成员变量。转移阶段是STW 的,其中内存分配通常耗时非常短,但对象成员变量的复制耗时有可能较长 (这个就跟redis大key似的)
118+
为什么转移阶段不能和标记阶段一样并发执行呢?
119+
主要是 G1 未能解决转移过程中准确定位对象地址的问题。
120+
G1 的 Young GC 和 CMS 的 Young GC,其标记 - 复制全过程 STW
121+
122+
ZGC 在标记、转移和重定位阶段几乎都是并发的,这是 ZGC 实现停顿时间小于 10ms 目标的最关键原因
123+
ZGC 通过着色指针和读屏障技术,解决了转移过程中准确访问对象的问题,实现了并发转移。
124+
ZGC 有多种 GC 触发机制
125+
阻塞内存分配请求触发:当垃圾来不及回收,垃圾将堆占满时,会导致部分线程阻塞。
126+
基于分配速率的自适应算法:最主要的 GC 触发方式
127+
基于固定时间间隔:通过 ZCollectionInterval 控制,适合应对突增流量场景。
128+
主动触发规则:类似于固定间隔规则,但时间间隔不固定,是 ZGC 自行算出来的时机
129+
预热规则:服务刚启动时出现,一般不需要关注
130+
外部触发:代码中显式调用 System.gc() 触发
131+
元数据分配触发:元数据区不足时导致,一般不需要关注
132+
133+
升级JDK11
134+
a. 一 些 类 被 删 除: 比 如“sun.misc.BASE64Encoder”, 找 到 替 换 类 java.util.Base64 即可。
135+
b. 组件依赖版本不兼容 JDK 11 问题:找到对应依赖组件,搜索最新版本,一般都支持 JDK 11。
136+
```
137+
### mybatis构建实现
98138
```
139+
SqlSession:作为 MyBatis 工作的主要顶层 API,表示和数据库交互的会话,完成必要数据库增删改查功能
140+
Executor:MyBatis 执行器,这是 MyBatis 调度的核心,负责 SQL 语句的生成和查询缓存的维护
141+
BoundSql:表示动态生成的 SQL 语句以及相应的参数信息
142+
StatementHandler: 封 装 了 JDBC Statement 操 作, 负 责 对 JDBCstatement 的操作,如设置参数、将 Statement 结果集转换成 List 集合等等
143+
ParameterHandler:负责对用户传递的参数转换成 JDBC Statement 所需要的参数
144+
TypeHandler:负责 Java 数据类型和 JDBC 数据类型之间的映射和转换
145+
```
146+
147+
### [ES集群如何进行挨个重启?](https://elasticsearch.cn/question/4454)
99148

100149
## linux查看哪个进程占用磁盘IO
101150
$ iotop -oP
102151
命令的含义:只显示有I/O行为的进程
103152

153+
$ iostat -dtxNm 2 10
154+
查看磁盘io状况
155+
156+
$ dstat -r -l -t --top-io
157+
用dstat命令看下io前几名的进程
158+
159+
$ dstat --top-bio-adv
160+
找到那个进程占用IO最多
161+
104162
$ pidstat -d 1
105163
命令的含义:展示I/O统计,每秒更新一次
106164

165+
网络上的人提供了如下三种解决方案:
166+
167+
升级内核
168+
更改commit的次数, "mount -o remount,commit=60 /dev/sda1"
169+
关闭文件系统日志功能: 操作类似于dumpe2fs 获取文件系统属性信息, tune2fs 调整文件系统属性, 之后e2fsck 检查文件系统(几乎大部分都不推荐这样做)
170+
当然这些方案,我一个都没有采纳,因为我突然想到今天服务器上似乎运行了许多IO操作很频繁的程序,jdb2的特点就是牺牲了性能保证了数据完整性,也就是说是我运行的程序太多让jdb2忙不过来了。
171+
172+
因此我的最终解决方案就是,用kill把所有当前运行的高IO程序都干掉。最后解决了问题
173+
107174
/Library/Java/JavaVirtualMachines/jdk-16.0.2.jdk/Contents/Home
108175
/Library/Java/JavaVirtualMachines/jdk-15.0.2.jdk/Contents/Home
109176
/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home

0 commit comments

Comments
 (0)