二十分钟带你了解JVM性能调优与实战进阶
ZGC
诞生原因
Java生态非常强大,但还不够,有些场景仍处于劣势,而ZGC的出现可以让Java语言抢占其他语言的某些特定领域市场。比如
- 谷歌主导的Android手机系统显示卡顿。
- 证券交易市场,实时性要求非常高,目前主要是C++主导。
- 大数据集群如HBase的性能。
特性
- ZGC(The Z Garbage Collector)为JDK11推出一款低延迟的垃圾回收器。STW即停顿时间低于1ms,且不会随着堆的大小增加而增加。
- 实现主要原理:全并发处理(仅对GC ROOTS进行遍历时会暂停)
- 高版本JDK16之后支持16TB级别的堆;
- 实现主要原理:Region分区管理、染色指针寻址
- 应用程序吞吐量最多减少15%。
- 实现主要原理:当生命周期很短的对象分配速率很高的时候,大量对象不会被进行标记收集,会产生大量浮动垃圾从而影响吞吐量,并且堆中可转移对象的空间就会越来越小。
- 为未来的GC新特性奠定基础。
- 实现主要原理:染色指针中未被使用预留的18 bits。
内存布局
ZGC采用堆空间分页模型的机制,堆空间分页模型也非常符合Linux Kernel2.6引入的标准大页(huge page)如4KB的处理方式。本质与G1一样,没有分代的概念,ZGC也采用基于Region的堆内存布局,不一样的是ZGC的Region具有动态性:动态创建销毁、动态容量大小。ZGC一共分为三种Region:
- 小型Region(小页面):容量固定为 2MB,存放小于256KB的对象。
- 中型Region(中页面):容量固定为 32MB,存放大于256KB小于4MB的对象。
- 大型Region(大页面):容量为 2*N MB,可以动态变化,每个大Region中只会存放一个大对象,并且不会被重分配(即后文介绍的对象的复制),因为大对象的复制代价高昂。
指针着色技术(Color Pointers)
- ZGC只支持64位的系统,也即是64位的指针。
- ZGC在JDK11的ZGC来分析中低42位即2的42次方来表示使用中的堆空间,也即是可管理的内存,而在JDK更高版本有所变化。
- ZGC借助几位高位来做GC相关的事情比如快速实现垃圾回收的并发标记、转移和重定位等。
- 预留用来给未来的GC新特性预留的扩展点
一段C程序mapping.c看下ZGC的64位虚拟地址空间的指针着色技术展示
编译执行,三个地址一样,也即是同一个实地址映射到3个虚地址。
整体流程
概述
主要分为两步
- 标记阶段(标记垃圾)
- 转移阶段(对象复制或移动)
垃圾标记
垃圾标记算法采用可达性分析算法
- Remapped
- GC前所有内存都是Remapped,或者标记后如果还是Remapped则是垃圾。
- M0,发生两次GC为例,M0是1次GC。
- 前一次GC的标记阶段被标记过的活跃对象,但是上次GC未对对象进行转移。
- M1,发生两次GC为例,M0是2次GC。
- 本次垃圾回收中识别的活跃对象。
标记阶段,对象分配(Remapped)
- 初始标记(标记根)
- 并发标记(标记剩余)
- 再标记(解决漏标)
标记结束后Remapped对象即为垃圾对象。而下次标记使用M1表示活跃。
ZGC转移
- 如果是同一个页面则等同于标记整理。
- 如果是不同页面等同于复制算法。
JVM调优概述
背景
- 生产环境中的问题
- 生产环境中的问题。
- 生产环境发生了内存溢出该如何处理?
- 生产环境应该给服务器分配多少内存合适?
- 如何对垃圾回收器的性能进行调优?
- 生产环境 CPU 负载飙高该如何处理?
- 生产环境应该给应用分配多少线程合适?
- 不加 log,如何确定请求是否执行了某一行代码?
- 不加 log,如何实时查看某个方法的入参与返回值?
- 为什么要调优
- 防止出现 OOM
- 解决 OOM
- 减少 Full GC 出现的频率
- 调优场景
- Full GC 次数频繁。
- GC 停顿时间过长(超过1秒)。
- 应用出现OutOfMemory 等内存异常。
- 系统吞吐量与响应性能不高或下降
- 不同阶段的考虑
- 上线前
- 项目运行阶段
- 线上出现 OOM
调优概述
- 监控的依据
- 运行日志
- 异常堆栈
- GC 日志
- 线程快照
- 堆转储快照
- 调优的大方向
- 合理地编写代码
- 充分并合理的使用硬件资源
- 合理地进行 JVM 调优
调优目标
JVM调优目标是使用较小的内存占用来获得较高的吞吐量或者较低的延迟,从这里也可以知道其重要指标有三个:
- 内存占用:程序正常运行需要的内存大小。
- 延迟:由于垃圾收集而引起的程序停顿时间。
- 吞吐量:用户程序运行时间占用户程序和垃圾收集占用总时间的比值。
从上面我们也知道这三者如同分布式CAP理论一样不可完全兼得,对于一个Java程序同时保证内存占用小、延迟低、高吞吐量是不可能的;任何一个指标性能的提高,几乎都是以牺牲其他指标性能的损为代价的,不可兼得。程序的目标不同,调优时所考虑的方向也不同,因此需要结合实际场景,有明确的优化目标,找到性能瓶颈,对瓶颈有针对性的优化。
调优原则
- 90%也即是大多数的Java应用不需要进行JVM优化。
- 大多数导致GC问题的原因是代码层面的问题导致的(代码层面)。
- 上线之前,应先考虑将机器的JVM参数设置到最优。
- 减少创建对象的数量,减少使用全局变量和大对象(代码层面)。
- 优先架构调优和代码调优,JVM优化是不得已的手段。
- 分析GC情况优化代码比优化JVM参数更好。
调优步骤
- 第 1 步:性能监控
- GC 频繁
- cpu load 过高(如top -hP 进程号;top -d 2 -c等)
- OOM
- 内存泄露
- 死锁
- 程序响应时间较长
- 第 2 步:性能分析
- 打印 GC 日志,通过 GCviewer 或者 gceasy来分析异常信息
- 灵活运用命令行工具、jstack、jmap、jinfo 等
- dump 出堆文件,使用内存分析工具分析文件
- 使用阿里 Arthas、jconsole、JVisualVM 来实时查看 JVM 状态
- jstack 查看堆栈信息
- 第 3 步:性能调优
- 适当增加内存,根据业务背景选择垃圾回收器
- 优化代码,控制内存使用
- 增加机器,分散节点压力
- 合理设置线程池线程数量
- 使用中间件提高程序效率,比如缓存、消息队列等
性能评价/测试指标
- 停顿时间(或响应时间)
- 提交请求和返回该请求的响应之间使用的时间,一般比较关注平均响应时间。
- 数据库查询一条记录(有索引),十几毫秒。
- 机械磁盘一次寻址定位。4毫秒
- 从机械磁盘顺序读取 1M 数据。2毫秒
- 从 SSD 磁盘顺序读取 1M 数据。0.3毫秒
- 从内存读取 1M 数据。十几微妙
- Java程序本地方法调用。几微妙
- 网络传输2Kb数据。1微妙
- 吞吐量
- 对单位时间内完成的工作量(请求)的量度
- 在 GC 中:运行用户代码的事件占总运行时间的比例(总运行时间:程序的运行时间+内存回收的时间)
- 吞吐量为 1-1/(1+n),其中-XX::GCTimeRatio=n
- 内存占用
- Java 堆区所占的内存大小
- 相互间的关系
- 以高速公路通行状况为例
- 吞吐量:每天通过高速公路收费站的车辆的数据
- 并发数:高速公路上正在行驶的车辆的数目
- 响应时间:车速
JVM监控及诊断命令行工具
无监控、不调优!命令行安装 jdk 的 bin 目录,这些工具用来获取目标 JVM 不同方面、不同层次的信息,帮助开发人员很好地解决 Java 应用程序的一些疑难杂症。
- 查看正在运行的Java进程:jps
- jps(Java Process Status):显示指定系统内所有的 HotSpot 虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。
- 对于本地虚拟机进程来说,进程的本地虚拟机 ID 与操作系统的进程 ID 是一致的,是唯一的。
- 基本使用语法为:jps [options] [hostid]
- 查看JVM统计信息:jstat
- jstat(JVM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据。在没有 GUI 图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。(一般生产环境没gui工具,简单可常用这个)
- 基本使用语法为:jstat - [-t] [-h] [ []],比如jstat -gc 进程id 1000 10
- jstat 还可以用来判断是否出现内存泄漏
- 在长时间运行的 Java 程序中,我们可以运行 jstat 命令连续获取多行性能数据,并取这几行数据中 OU 列(即已占用的老年代内存)的最小值。
- 然后,我们每隔一段较长的时间重复一次上述操作,来获得多组 OU 最小值。如果这些值呈上涨趋势,则说明该 Java 程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。
- 实时查看和修改JVM配置参数:jinfo
- jinfo(Configuration Info for Java):查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数
- 基本使用语法为:jinfo [options] pid,比如jinfo -sysprops 进程id
- 导出内存映像文件&内存使用情况:jmap
- 获取 dump 文件(堆转储快照文件,二进制文件),它还可以获取目标 Java 进程的内存相关信息,包括 Java 堆各区域的使用情况、堆中对象的统计信息、类加载信息等。
- 基本使用语法为:
- jmap [option]
- jmap [option] <executable
- jmap [option] [server_id@]
- 使用1:导出内存映像文件
- 手动的方式
- jmap -dump:format=b,file=<filename.hprof>
- jmap -dump:live,format=b,file=<filename.hprof>
- 使用2:显示堆内存相关信息
- jmap -heap 进程id
- jmap -histo 进程id
- 使用3:其他作用
- jmap -permstat 进程id
- 查看系统的ClassLoader信息
- jmap -finalizerinfo
- 查看堆积在finalizer队列中的对象
- JDK 自带堆分析工具:jhat
- jhat(JVM Heap Analysis Tool):Sun JDK 提供的 jhat 命令与 jmap 命令搭配使用,用于分析 jmap 生成的 heap dump 文件(堆转储快照)。jhat 内置了一个微型的 HTTP/HTML 服务器,生成 dump 文件的分析结果后,用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)。
- 使用了 jhat 命令,就启动了一个 http 服务,端口是 7000,即 http://localhost:7000/,就可以在浏览器里分析。
- 说明:jhat 命令在 JDK9、JDK10 中已经被删除,官方建议用 VisualVM 代替。
- 基本适用语法:jhat
- 打印JVM中线程快照:jstack
- jstack(JVM Stack Trace):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。
- 生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用 jstack 显示各个线程调用的堆栈情况。
- 基本语法 : jstack [option] pid
- 多功能命令行:jcmd
- 在 JDK 1.7 以后,新增了一个命令行工具 jcmd。它是一个多功能的工具,可以用来实现前面除了 jstat 之外所有命令的功能。比如:用它来导出堆、内存使用、查看 Java 进程、导出线程信息、执行 GC、JVM 运行时间等。
- jcmd -l:列出所有的 JVM 进程
- jcmd pid help:针对指定的进程,列出支持的所有具体命令
- jcmd pid 具体命令:显示指定进程的指令命令的数据
- 远程主机信息收集:jstatd
- 之前的指令只涉及到监控本机的 Java 应用程序,而在这些工具中,一些监控工具也支持对远程计算机的监控(如 jps、jstat)。为了启用远程监控,则需要配合使用 jstatd 工具。命令 jstatd 是一个 RMI 服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd 服务器将本机的 Java 应用程序信息传递到远程计算机。
JVM监控及诊断工具GUI
前面我们学习Arthas也是一种JVM监控及诊断工具GUI,本篇先抛出影子,后续在单独针对
- JDK自带的工具
- jconsole:JDK 自带的可视化监控工具。查看 Java 应用程序的运行概况、监控堆信息、永久区(或元空间)使用情况、类加载情况等。
- 从 Java5 开始,在 JDK 中自带的 java 监控和管理控制台。用于对 JVM 中内存、线程和类等的监控,是一个基于 JMX(java management extensions)的 GUI 性能监控工具。
- Visual VM:Visual VM 是一个工具,它提供了一个可视界面,用于查看 Java 虚拟机上运行的基于 Java 技术的应用程序的详细信息。
- VisualVM是–个功能强大的多合一故障诊断和性能监控的可视化工具。
- 它集成了多个JDK命令行工具,使用VisualVM可用于显示虚拟机进程及进程的配置和环境信息(jps ,jinfo),监视应用程序的CPU、GC、堆、方法区及线程的信息(jstat、jstack)等,替JConsole。
- 在JDK 6 Update 7以后,Visual VM便作为JDK的一 部分发布(VisualVM 在JDK/bin目录下)。此外,Visual VM也可以作为独立的软件安装。
- JMC:Java Mission Control,内置 Java Flight Recorder。能够以极低的性能开销收集 Java 虚拟机的性能数据。
- 第三方工具
- MAT:MAT(Memory Analyzer Tool)是基于 Eclipse 的内存分析工具,是一个快速、功能丰富的 Java heap 分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。
- MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun,HP,SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析。
- 最吸引人的还是能够快速为开发人员生成内存泄漏报表,方便定位问题和分析问题。虽然 MAT 有如此强大的功能,但是内存分析也没有简单到一键完成的程度,很多内存问题还是需要我们从 MAT 展现给我们的信息当中通过经验和直觉来判断才能发现。
- JProfiler:商业软件,需要付费。功能强大。
- Flame Graphs(火焰图),在追求极致性能的场景下,了解你的程序运行过程中 cpu 在干什么很重要,火焰图就是一种非常直观的展示 CPU 在程序整个生命周期过程中时间分配的工具和调用找中的 CPU 消耗瓶颈。
此外针对JVM运行时参数和分析GC日志再单独增加专题文档
相关文章:

二十分钟带你了解JVM性能调优与实战进阶
ZGC 诞生原因 Java生态非常强大,但还不够,有些场景仍处于劣势,而ZGC的出现可以让Java语言抢占其他语言的某些特定领域市场。比如 谷歌主导的Android手机系统显示卡顿。证券交易市场,实时性要求非常高,目前主要是C主…...
对比应用层和内核层区别
一、所使用的空间不同: 应用层使用的空间是0-3G的用户空间。 内核层使用的是3-4G的内核空间。 二、打印信息所用函数不同: 应用层使用printf打印信息。 printf("打印信息\n"); 内核层使用printk打印信息。 …...

Hadoop服役新服务器
目录 0、准备一台新服务器 1、修改主机名 2、配置静态ip 3、配置xshell登录 4、关闭并禁用防火墙 5、分发hadoop和jdk文件 6、分发环境变量文件 7、source 环境变量 8、配置ssh 9、删除105节点的data、logs文件夹 10、单节点启动并关联到集群 11、验证新节点是否有效 0…...

YOLOv8详解 【网络结构+代码+实操】
文章目录YOLOv8 概述模型结构Loss 计算训练数据增强训练策略模型推理过程网络模型解析卷积神经单元(model.py)Yolov8实操快速入门环境配置数据集准备模型的训练/验证/预测/导出使用CLI使用python多任务支持检测实例分割分类配置设置操作类型训练预测验证…...

Visual Studio Code 1.76 发布
欢迎使用 Visual Studio Code 2023 年 2 月版,其中一些亮点包括: 配置文件 - 活动配置文件徽章,通过命令面板快速切换配置文件。辅助功能改进 - 新的音频提示,改进的终端屏幕阅读器模式。可移动的 Explorer 视图- 将资源管理器放…...

Vulnhub靶场----3、DC-3.2
文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 靶场下载地址:https://download.vulnhub.com/dc/DC-3-2.zip kali:192.168.144.148 DC-3.2:192.168.144.151 更改驱动器连接设置: 二、渗透流程 1、信息收集nmap -T5 -…...

Windows电脑密码忘记解决方法
目录 背景 方法一 方法二 方法三 方法四 方法五 背景 个人电脑忘记了密码,无法登录用户界面。 方法一 1. 开机时常按 F11,如果是Win10一下系统,就常按 F8,知道出现一下图状 2. 选择疑难解答,再选择高级选项 3.…...
ChatGPT相关技术必读论文100篇(2.27日起,几乎每天更新)
按上篇文章《ChatGPT技术原理解析:从RL之PPO算法、RLHF到GPT-N、instructGPT》的最后所述 为了写本ChatGPT笔记,过去两个月翻了大量中英文资料/paper(中间一度花了大量时间去深入RL),大部分时间读的更多是中文资料 2月最后几天读的更多是英文…...

【算法】算法题解---电话号码的字符组合
算法名称 电话号码的字符组合 算法描述 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入&…...

提高上限之数学学习——数制转换及MECE原则学习
文章目录数制转换不同数制表达数制转换的方法换基法(换向十进制)除余法(十进制向其他进制转换)按位拆分法和按位合并法判断一个整数a,是否是2的整数次幂MECE原则学习数制转换 不同数制表达 数制转换的方法 换基法(换向十进制) 定义:给出数制转换的定量…...

字符函数和字符串函数(下)——“C”
各位CSDN的uu们你们好呀,今天小雅兰的内容依旧是字符函数和字符串函数呀,这篇博客会讲一些内存相关的函数,下面,让我们进入字符函数和字符串函数的世界吧 字符串查找 strstr strtok 错误信息报告 strerror 字符操作 内存操作函…...

kafka docker 安装
先启动起 zookeeper (1)服务: 192.168.190.35docker run -d --name kafka1 \-p 9092:9092 \-e KAFKA_BROKER_ID0 \-e delete.topic.enabletrue \-e num.partitions1 \-e KAFKA_ZOOKEEPER_CONNECT192.168.192.35:2181 \-e KAFKA_ADVERTISED_LI…...

SpringBean管理
一.什么是SpringBean? 在Spring中将管理对象称为 Bean.Bean是由一个SpringIOC容器实例化,组装和管理的对象.也就是说,Bean并不是由我们程序员编写的,而是在程序运行过程中,由Spring通过反射机制生成的. SpringBean是Spring框架在运行时管理的对象,我们编写的大多数逻辑代码都…...
关于Vue3中reactive的意义
在学习Vue3的时候产生疑问: const addForm reactive({ // 这里面的reactive啥意思sysPre: null,diaPre: null,tem: null })查询解决 在Vue3中,响应式对象是指通过reactive函数转换而来的对象,它的属性可以被Vue自动监测,当属性…...

平衡三进制
平衡三进制 一、定义 平衡三进制,也称为对称三进制。这是一个不太标准的 计数体系。 正规的三进制的数字都是由 0,1,2 构成的,而平衡三进制的数字是由 -1,0,1 构成的。它的基数也是 3(因为有三个可能的值)。由于将 -1 写成数字…...

python爬取网站数据
开学前接了一个任务,内容是从网上爬取特定属性的数据。正好之前学了python,练练手。 编码问题 因为涉及到中文,所以必然地涉及到了编码的问题,这一次借这个机会算是彻底搞清楚了。 Unicode是一种编码方案,又称万国码…...

CSS的三大特性
🌟所属专栏:前端只因变凤凰之路🐔作者简介:rchjr——五带信管菜只因一枚😮前言:该系列将持续更新前端的相关学习笔记,欢迎和我一样的小白订阅,一起学习共同进步~👉文章简…...

Linux-scheduler之负载均衡(二)
四、调度域 SDTL结构 linux内核使用SDTL结构体来组织CPU的层次关系 struct sched_domain_topology_level {sched_domain_mask_f mask; //函数指针,用于指定某个SDTL的cpumask位图sched_domain_flags_f sd_flags; //函数指针,用于指定某个SD…...

VScode第三方插件打开sqlite数据库
文章目录前言对比1.文本文件、表格软件打开2.专业软件3.pythonVScode 第三方库打开数据库1. 下载第三方库插件2.打开sqlite新建查询3.输入查询内容前言 最近在做的东西涉及SQLite数据库(一种常用在移动端的数据库类型,和mysql这些主流数据库也差不多&am…...
Kafka 监控
Kafka 监控主机监控JVM 监控集群监控监控 Kafka 客户端主机监控 主机监控 : 监控 Kafka 集群 Broker 所在的节点机器的性能 主机监控指标 : 机器负载 (Load) , CPU 使用率内存使用率 (空闲内存 , 已使用内存 (Used Memory) )磁盘 I/O 使用率 (读使用率/ 写使用率) , 网络 I/…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...