<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>面试八股 on 方糖猫Blog</title>
    <link>https://ftmao.com/blog/tags/%E9%9D%A2%E8%AF%95%E5%85%AB%E8%82%A1/</link>
    <description>AI 视频、AI Agent 与工程实践笔记</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Tue, 28 Sep 2021 10:00:00 +0800</lastBuildDate><atom:link href="https://ftmao.com/blog/tags/%E9%9D%A2%E8%AF%95%E5%85%AB%E8%82%A1/index.xml" rel="self" type="application/rss+xml" /><item>
      <title>从Redis核心原理到 IPTV 视频项目落地</title>
      <link>https://ftmao.com/blog/posts/redis-in-action-iptv/</link>
      <pubDate>Tue, 28 Sep 2021 10:00:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/posts/redis-in-action-iptv/</guid>
      <description>&lt;h1 id=&#34;从redis核心原理到-iptv-视频项目落地&#34;&gt;从Redis核心原理到 IPTV 视频项目落地&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;先系统梳理 Redis 的核心原理与面试高频知识点，再结合 IPTV（交互式网络电视）视频业务场景，给出可直接运行的 Demo。最后讨论 Redis 为什么不适合长期存储、常见踩坑点，以及 List / Pub/Sub / Stream 三种消息队列实现。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一redis-是什么一句话定位&#34;&gt;一、Redis 是什么？一句话定位&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Redis（Remote Dictionary Server）是一个开源的、基于内存的高性能键值对数据库&lt;/strong&gt;，支持多种数据结构、持久化、高可用与分布式扩展。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[Redis] --&amp;gt; B[内存存储]
    A --&amp;gt; C[数据结构服务器]
    A --&amp;gt; D[单线程命令执行]
    A --&amp;gt; E[IO 多路复用]
    A --&amp;gt; F[持久化 + 高可用]
    B --&amp;gt; G[读写毫秒级]
    C --&amp;gt; H[String/Hash/List/Set/ZSET/Stream/Bitmap/Geo/HyperLogLog]
    F --&amp;gt; I[RDB/AOF/主从/哨兵/Cluster]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;与 Memcached 等纯缓存不同，Redis 的核心价值在于&lt;strong&gt;丰富的数据结构与原子操作&lt;/strong&gt;，可以直接在内存中完成排序、计数、限流、去重、队列等复杂逻辑。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二redis-为什么快&#34;&gt;二、Redis 为什么快？&lt;/h2&gt;
&lt;p&gt;面试常问「Redis 为什么快」，通常从四个层面回答：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;原因&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;内存操作&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;数据存于内存，无需磁盘寻道，访问速度是 SSD 的千倍以上。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;单线程命令执行&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;避免多线程上下文切换、锁竞争，CPU 缓存命中率更高。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;IO 多路复用&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;基于 epoll/kqueue/select 用一个线程处理大量连接。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;高效数据结构&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;String 底层 SDS、ZSET 底层跳表+字典、List 底层 quicklist 等。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TB
    subgraph Redis 6/7 线程模型
        M[主线程&amp;lt;br/&amp;gt;命令执行 + IO 多路复用]
        IO[IO 线程池&amp;lt;br/&amp;gt;仅网络读写]
        BG[后台进程&amp;lt;br/&amp;gt;RDB fork / AOF rewrite]
    end
    C1[Client 1] --&amp;gt; M
    C2[Client 2] --&amp;gt; M
    C3[Client 3] --&amp;gt; M
    M &amp;lt;--&amp;gt; IO
    M -.-&amp;gt; BG&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;注意：Redis 6/7 引入的多线程&lt;strong&gt;只用于网络 IO 读写&lt;/strong&gt;，命令执行依旧是单线程。所以单条慢命令仍会阻塞整个实例。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三redis-数据类型与使用场景&#34;&gt;三、Redis 数据类型与使用场景&lt;/h2&gt;
&lt;h3 id=&#34;31-五种基本数据类型&#34;&gt;3.1 五种基本数据类型&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;类型&lt;/th&gt;
					&lt;th&gt;底层结构&lt;/th&gt;
					&lt;th&gt;典型场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;String&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;SDS（简单动态字符串）&lt;/td&gt;
					&lt;td&gt;缓存、计数器、分布式锁、Session&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Hash&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;ziplist / hashtable&lt;/td&gt;
					&lt;td&gt;对象缓存、用户信息、EPG 节目单&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;List&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;quicklist（ziplist + 双向链表）&lt;/td&gt;
					&lt;td&gt;消息队列、最新 N 条记录&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Set&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;intset / hashtable&lt;/td&gt;
					&lt;td&gt;去重、共同关注、抽奖&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ZSET&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;ziplist / skiplist + dict&lt;/td&gt;
					&lt;td&gt;排行榜、延时队列、范围查询&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;注：表中 ziplist 在 Redis 7 起已被 listpack 替代（动机见 §4.2），配置项改名 &lt;code&gt;*-max-listpack-*&lt;/code&gt;，旧名仍兼容。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;32-三种特殊数据类型&#34;&gt;3.2 三种特殊数据类型&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;类型&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
					&lt;th&gt;场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Bitmap&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;位数组，按位操作&lt;/td&gt;
					&lt;td&gt;用户签到、在线状态、UV 统计&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;HyperLogLog&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;基数估计算法&lt;/td&gt;
					&lt;td&gt;海量 UV 去重计数，误差约 0.81%&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Geo&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;地理位置坐标&lt;/td&gt;
					&lt;td&gt;附近的人、POI 搜索&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;33-string最常用却被低估&#34;&gt;3.3 String：最常用却被低估&lt;/h3&gt;
&lt;p&gt;String 不仅能存字符串，还能存整数、浮点数、二进制数据。常用命令：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SET key value EX &lt;span style=&#34;color:#ae81ff&#34;&gt;3600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;GET key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INCR view_count
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INCRBY view_count &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SETNX lock:order:123 true EX &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# 分布式锁核心命令&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;SDS 的优势&lt;/strong&gt;（相对 C 字符串）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O(1) 获取长度。&lt;/li&gt;
&lt;li&gt;二进制安全，可存图片、序列化数据。&lt;/li&gt;
&lt;li&gt;预分配空间，减少内存重分配次数。&lt;/li&gt;
&lt;li&gt;杜绝缓冲区溢出。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;34-hash对象缓存首选&#34;&gt;3.4 Hash：对象缓存首选&lt;/h3&gt;
&lt;p&gt;Hash 适合存「一组字段」的对象，比 JSON String 更节省内存、更新更灵活。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HSET user:1001 name &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;张三&amp;#34;&lt;/span&gt; age &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt; city &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;北京&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HGET user:1001 name
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HGETALL user:1001
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HINCRBY user:1001 age &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;35-zset排行榜的王牌&#34;&gt;3.5 ZSET：排行榜的王牌&lt;/h3&gt;
&lt;p&gt;ZSET 底层同时维护「跳表」和「字典」：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;跳表（skiplist）&lt;/strong&gt;：支持 O(log N) 的范围查询和排序。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;字典（dict）&lt;/strong&gt;：支持 O(1) 按 member 查 score。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ZADD hot:tv &lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;庆余年&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ZADD hot:tv &lt;span style=&#34;color:#ae81ff&#34;&gt;800&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;狂飙&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ZINCRBY hot:tv &lt;span style=&#34;color:#ae81ff&#34;&gt;50&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;狂飙&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ZREVRANGE hot:tv &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;9&lt;/span&gt; WITHSCORES
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ZREVRANK hot:tv &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;狂飙&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;36-list-与-stream队列双雄&#34;&gt;3.6 List 与 Stream：队列双雄&lt;/h3&gt;
&lt;p&gt;List 适合简单队列，Stream 适合生产级消息队列，后面第十四部分会详细对比。&lt;/p&gt;
&lt;h3 id=&#34;37-bitmap-与-hyperloglog海量-uv-统计的利器&#34;&gt;3.7 Bitmap 与 HyperLogLog：海量 UV 统计的利器&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Bitmap 为什么能天然去重？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bitmap 本质是一个超长 bit 数组，每个 bit 只能是 0 或 1。把 user_id 作为偏移量（offset），用户访问一次就把对应位置 1：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;天然去重&lt;/strong&gt;：同一用户重复访问，置的都是同一个 bit，无需额外判断。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;极致省内存&lt;/strong&gt;：1 亿用户只需 1 亿 bit ≈ 12MB；而 Set 存 1 亿个 ID 要占用数 GB。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;支持位运算&lt;/strong&gt;：&lt;code&gt;BITOP AND/OR&lt;/code&gt; 可以直接算多日留存（今天访问 AND 昨天也访问）。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SETBIT uv:20210928 &lt;span style=&#34;color:#ae81ff&#34;&gt;10086&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# 用户 10086 访问&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SETBIT uv:20210928 &lt;span style=&#34;color:#ae81ff&#34;&gt;10086&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# 重复访问，结果不变&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;BITCOUNT uv:20210928         &lt;span style=&#34;color:#75715e&#34;&gt;# 直接得出 UV 数&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;局限：要求 user_id 是连续整数，ID 稀疏时浪费内存。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HyperLogLog 为什么 12KB 能数一亿？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HyperLogLog 基于概率估计算法：把每个元素 hash 成均匀分布的随机数，观察 hash 值二进制串中&lt;strong&gt;前导零的最大个数&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;类比抛硬币：想连续抛出 N 次正面，平均要抛 2^N 次。反过来，如果见过最长连续 N 次正面，就估计大约抛了 2^N 次——前导零越多，说明见过的不同元素越多。&lt;/li&gt;
&lt;li&gt;单次估计误差大，所以内部用 &lt;strong&gt;16384 个分桶（寄存器，每个 6 bit）&lt;/strong&gt; 分别记录，再取调和平均数消除偶然性，最终误差稳定在 &lt;strong&gt;0.81%&lt;/strong&gt; 左右。&lt;/li&gt;
&lt;li&gt;内存恒定 &lt;strong&gt;约 12KB&lt;/strong&gt;，与元素个数无关：统计 1 亿 UV 还是 10 亿 UV 都是 12KB。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PFADD uv:20210928 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user:10086&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PFADD uv:20210928 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user:10086&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# 重复添加不影响计数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PFCOUNT uv:20210928             &lt;span style=&#34;color:#75715e&#34;&gt;# 估算 UV&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;局限：有误差、不可逆（不能取出具体是哪些用户）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;怎么选&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;需求&lt;/th&gt;
					&lt;th&gt;推荐&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;精确计数、算多日留存（交并集）、ID 是连续整数&lt;/td&gt;
					&lt;td&gt;Bitmap&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;只要近似 UV、数据量极大、ID 是任意字符串&lt;/td&gt;
					&lt;td&gt;HyperLogLog&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四redis-底层数据结构速览&#34;&gt;四、Redis 底层数据结构速览&lt;/h2&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
    A[Redis 数据类型] --&amp;gt; B[String]
    A --&amp;gt; C[Hash]
    A --&amp;gt; D[List]
    A --&amp;gt; E[Set]
    A --&amp;gt; F[ZSET]
    B --&amp;gt; G[SDS]
    C --&amp;gt; H[ziplist]
    C --&amp;gt; I[hashtable]
    D --&amp;gt; J[quicklist]
    E --&amp;gt; K[intset]
    E --&amp;gt; L[hashtable]
    F --&amp;gt; M[ziplist]
    F --&amp;gt; N[skiplist + dict]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;底层结构&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SDS&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;带长度、预分配、二进制安全。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ziplist&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;紧凑列表，小数据量时省内存；大数据量时改为 hashtable/skiplist。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;listpack&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;ziplist 的修正版（Redis 7+）：entry 只记自身长度，消灭连锁更新。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;quicklist&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;List 的底层，由多个紧凑块（Redis 7 前是 ziplist，之后是 listpack）节点组成的双向链表。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;hashtable&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;标准哈希表，渐进式 rehash 避免一次性阻塞。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;intset&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Set 在元素全为整数且数量少时的紧凑实现。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;skiplist&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;多层索引链表，实现 ZSET 的有序范围查询。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;下面把 5 种核心结构「画」出来。&lt;/p&gt;
&lt;h3 id=&#34;41-sdssimple-dynamic-string&#34;&gt;4.1 SDS（Simple Dynamic String）&lt;/h3&gt;
&lt;p&gt;Redis 没有直接用 C 字符串，而是包了 SDS：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    L[&amp;#34;len&amp;lt;br/&amp;gt;已用长度（4B）&amp;lt;br/&amp;gt;= 5&amp;#34;] --- A[&amp;#34;alloc&amp;lt;br/&amp;gt;总容量&amp;lt;br/&amp;gt;= 8&amp;#34;] --- F[&amp;#34;flags&amp;lt;br/&amp;gt;编码位&amp;lt;br/&amp;gt;= 0&amp;#34;] --- B[&amp;#34;buf[]&amp;lt;br/&amp;gt;实际字符/二进制数据&amp;lt;br/&amp;gt;H e l l o \0 ...&amp;#34;]
    N1[&amp;#34;O(1) 取长度&amp;#34;] -.-&amp;gt; L
    N2[&amp;#34;末尾保留 \0&amp;lt;br/&amp;gt;兼容 C 字符串函数&amp;#34;] -.-&amp;gt; B&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;len&lt;/code&gt;：已用长度，取长度 &lt;code&gt;O(1)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;alloc&lt;/code&gt;：分配的总空间；&lt;code&gt;free = alloc - len&lt;/code&gt; 可减少内存重分配。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;二进制安全&lt;/strong&gt;：内容中间可以有 &lt;code&gt;\0&lt;/code&gt;，长度由 &lt;code&gt;len&lt;/code&gt; 决定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;预分配&lt;/strong&gt;：修改时若 &lt;code&gt;free&lt;/code&gt; 足够就不 &lt;code&gt;realloc&lt;/code&gt;；不足时按 2 倍或 1MB 上限预分配。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;42-ziplist压缩列表&#34;&gt;4.2 ziplist（压缩列表）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ziplist&lt;/code&gt; 是一块连续内存，把所有 entry 紧凑排列：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[&amp;#34;zlbytes&amp;lt;br/&amp;gt;总字节数&amp;lt;br/&amp;gt;4B&amp;#34;] --- B[&amp;#34;zltail&amp;lt;br/&amp;gt;尾偏移量&amp;lt;br/&amp;gt;4B&amp;#34;] --- C[&amp;#34;zllen&amp;lt;br/&amp;gt;节点数&amp;lt;br/&amp;gt;2B&amp;#34;] --- D[&amp;#34;entry1&amp;lt;br/&amp;gt;变长字节&amp;#34;] --- E[&amp;#34;entry2&amp;lt;br/&amp;gt;变长字节&amp;#34;] --- F[&amp;#34;...&amp;#34;] --- G[&amp;#34;zlend&amp;lt;br/&amp;gt;0xFF&amp;lt;br/&amp;gt;1B&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;每个 entry 的内部结构：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[&amp;#34;prevlen&amp;lt;br/&amp;gt;前节点长度&amp;lt;br/&amp;gt;1B 或 5B&amp;#34;] --- B[&amp;#34;encoding&amp;lt;br/&amp;gt;编码/长度类型&amp;lt;br/&amp;gt;1B 或更多&amp;#34;] --- C[&amp;#34;content&amp;lt;br/&amp;gt;实际数据&amp;lt;br/&amp;gt;变长&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;ul&gt;
&lt;li&gt;连续内存、无额外指针，所以&lt;strong&gt;省内存&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;插入/删除需要整体 &lt;code&gt;memmove&lt;/code&gt;，因此只用于&lt;strong&gt;小数据量&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Hash/List/ZSET&lt;/code&gt; 元素少且单元素短时先用 ziplist，超过阈值升级为 hashtable/skiplist。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;listpack（Redis 7 的替代者）&lt;/strong&gt;：ziplist 的致命伤就藏在 &lt;code&gt;prevlen&lt;/code&gt; 里——每个 entry 要记录&lt;strong&gt;前一个&lt;/strong&gt; entry 的长度：前 entry 小于 254 字节时 prevlen 占 1B，达到 254 字节时占 5B。于是一个 entry 从 253 涨到 254 字节，会让后面每个 entry 的 prevlen 从 1B 膨胀到 5B，膨胀又可能触发下一个 entry 继续膨胀——&lt;strong&gt;连锁更新&lt;/strong&gt;，最坏 O(N²)。&lt;/p&gt;
&lt;p&gt;listpack 的修法：&lt;strong&gt;每个 entry 只记录自己的总长度，且存在 entry 末尾&lt;/strong&gt;，entry 之间互不引用——改任何一个 entry 都不会波及邻居，连锁更新从根上消失。Redis 7 起 Hash/List/ZSET 的小对象编码全部换成 listpack，配置项同步改名（&lt;code&gt;hash-max-listpack-entries&lt;/code&gt; 等，旧的 &lt;code&gt;*-ziplist-*&lt;/code&gt; 名仍兼容）。面试回答「ziplist 和 listpack 的区别」，核心就是这一句：&lt;strong&gt;ziplist 记前驱长度所以连锁更新，listpack 记自身长度所以免疫&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;43-quicklist快速列表&#34;&gt;4.3 quicklist（快速列表）&lt;/h3&gt;
&lt;p&gt;Redis 3.2 后，&lt;code&gt;List&lt;/code&gt; 的底层是 &lt;strong&gt;quicklist = 双向链表 + ziplist&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    H[&amp;#34;head&amp;#34;] --&amp;gt; A[&amp;#34;ziplist A&amp;lt;br/&amp;gt;[a|b|c]&amp;lt;br/&amp;gt;count=3&amp;lt;br/&amp;gt;sz=...&amp;#34;] &amp;lt;--&amp;gt; B[&amp;#34;ziplist B&amp;lt;br/&amp;gt;[d|e|f|g]&amp;lt;br/&amp;gt;count=4&amp;lt;br/&amp;gt;sz=...&amp;#34;] &amp;lt;--&amp;gt; C[&amp;#34;...&amp;#34;]
    N[&amp;#34;每个节点是一个 ziplist&amp;lt;br/&amp;gt;节点之间用 prev/next 指针连接&amp;#34;] -.-&amp;gt; A&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;quicklistNode 结构：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[&amp;#34;prev&amp;lt;br/&amp;gt;指针&amp;#34;] --- B[&amp;#34;next&amp;lt;br/&amp;gt;指针&amp;#34;] --- C[&amp;#34;zl&amp;lt;br/&amp;gt;ziplist&amp;#34;] --- D[&amp;#34;sz&amp;lt;br/&amp;gt;字节数&amp;#34;] --- E[&amp;#34;count&amp;lt;br/&amp;gt;元素个数&amp;#34;] --- F[&amp;#34;encoding&amp;lt;br/&amp;gt;是否压缩&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;ul&gt;
&lt;li&gt;结合了双向链表「插入删除快」和 ziplist「省内存」的优点。&lt;/li&gt;
&lt;li&gt;每个节点只存少量元素，避免单个 ziplist 太大导致 &lt;code&gt;memmove&lt;/code&gt; 开销。&lt;/li&gt;
&lt;li&gt;Redis 7 起节点从 ziplist 换成 listpack（动机见 §4.2），但 quicklist 的「链表 + 紧凑块」思想不变。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;44-intset整数集合&#34;&gt;4.4 intset（整数集合）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Set&lt;/code&gt; 在元素&lt;strong&gt;全为整数且数量少&lt;/strong&gt;时使用 intset，否则升级为 &lt;code&gt;hashtable&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[&amp;#34;encoding&amp;lt;br/&amp;gt;编码类型&amp;lt;br/&amp;gt;2B/4B/8B&amp;#34;] --- B[&amp;#34;length&amp;lt;br/&amp;gt;元素个数&amp;lt;br/&amp;gt;4B&amp;#34;] --- C[&amp;#34;contents[]&amp;lt;br/&amp;gt;有序整数数组&amp;lt;br/&amp;gt;[1] [3] [5] [7] [9] ...&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;ul&gt;
&lt;li&gt;有序数组，支持二分查找 &lt;code&gt;O(log N)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;所有元素用同一 encoding；加入更大范围整数时可能整体升级（如 int16 → int32），升级是 &lt;code&gt;O(N)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;无重复元素（Set 语义）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;45-skiplist跳表&#34;&gt;4.5 skiplist（跳表）&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ZSET&lt;/code&gt; 同时维护 &lt;strong&gt;skiplist + dict&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;skiplist&lt;/code&gt;：按 score 排序，支持范围查询 / 排名 &lt;code&gt;O(log N)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dict&lt;/code&gt;：按 member 查 score，&lt;code&gt;O(1)&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;普通有序链表只能顺序扫描，跳表加了多层「快速通道」：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph L3[&amp;#34;level 3&amp;#34;]
        A3[&amp;#34;1&amp;#34;] --&amp;gt; B3[&amp;#34;9&amp;#34;] --&amp;gt; C3[&amp;#34;15&amp;#34;]
    end
    subgraph L2[&amp;#34;level 2&amp;#34;]
        A2[&amp;#34;1&amp;#34;] --&amp;gt; B2[&amp;#34;5&amp;#34;] --&amp;gt; C2[&amp;#34;9&amp;#34;] --&amp;gt; D2[&amp;#34;13&amp;#34;] --&amp;gt; E2[&amp;#34;15&amp;#34;]
    end
    subgraph L1[&amp;#34;level 1&amp;#34;]
        A1[&amp;#34;1&amp;#34;] --&amp;gt; B1[&amp;#34;3&amp;#34;] --&amp;gt; C1[&amp;#34;5&amp;#34;] --&amp;gt; D1[&amp;#34;7&amp;#34;] --&amp;gt; E1[&amp;#34;9&amp;#34;] --&amp;gt; F1[&amp;#34;11&amp;#34;] --&amp;gt; G1[&amp;#34;13&amp;#34;] --&amp;gt; H1[&amp;#34;15&amp;#34;]
    end
    A3 --- A2 --- A1
    B3 --- C2 --- E1
    C3 --- E2 --- H1
    HEAD[&amp;#34;头节点&amp;#34;] -.-&amp;gt; A1
    H1 -.-&amp;gt; TAIL[&amp;#34;尾节点&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;跳表节点结构：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    A[&amp;#34;member&amp;lt;br/&amp;gt;成员字符串&amp;lt;br/&amp;gt;（sds）&amp;#34;] --- B[&amp;#34;score&amp;lt;br/&amp;gt;分数&amp;lt;br/&amp;gt;（double）&amp;#34;] --- C[&amp;#34;forward[] 数组&amp;lt;br/&amp;gt;[L1指针， L2指针， L3指针， ...]&amp;lt;br/&amp;gt;最高层数 = 随机 1~32&amp;#34;]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;概率平衡&lt;/strong&gt;：不用像红黑树那样做复杂旋转。&lt;/li&gt;
&lt;li&gt;查找 &lt;code&gt;score=11&lt;/code&gt; 时，先在高层大步跳跃，再逐层下降，平均 &lt;code&gt;O(log N)&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;配合 dict 实现 &lt;code&gt;ZSCORE&lt;/code&gt; 的 &lt;code&gt;O(1)&lt;/code&gt; 查询。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;五redis-持久化rdb-与-aof&#34;&gt;五、Redis 持久化：RDB 与 AOF&lt;/h2&gt;
&lt;p&gt;Redis 提供两种持久化方式，各有优劣。&lt;/p&gt;
&lt;h3 id=&#34;51-rdbredis-database&#34;&gt;5.1 RDB（Redis Database）&lt;/h3&gt;
&lt;p&gt;在指定时间间隔内将内存数据集快照写入磁盘。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;save &lt;span style=&#34;color:#ae81ff&#34;&gt;900&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;      &lt;span style=&#34;color:#75715e&#34;&gt;# 900 秒内至少 1 次修改则触发&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;save &lt;span style=&#34;color:#ae81ff&#34;&gt;300&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;     &lt;span style=&#34;color:#75715e&#34;&gt;# 300 秒内至少 10 次修改则触发&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;save &lt;span style=&#34;color:#ae81ff&#34;&gt;60&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10000&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# 60 秒内至少 10000 次修改则触发&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文件紧凑，适合备份和灾难恢复。&lt;/li&gt;
&lt;li&gt;恢复速度快。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;两次快照之间数据可能丢失。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bgsave&lt;/code&gt; 通过 &lt;code&gt;fork()&lt;/code&gt; 子进程生成，大数据集时可能阻塞主线程。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;52-aofappend-only-file&#34;&gt;5.2 AOF（Append Only File）&lt;/h3&gt;
&lt;p&gt;将每次写操作命令追加到日志文件。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;appendonly yes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;appendfsync everysec  &lt;span style=&#34;color:#75715e&#34;&gt;# 每秒刷盘一次（推荐）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# appendfsync always  # 每次写都刷盘，最安全但最慢&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# appendfsync no      # 由操作系统决定，最快但不安全&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据安全性更高，默认最多丢失 1 秒数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;缺点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文件体积大。&lt;/li&gt;
&lt;li&gt;恢复速度慢。&lt;/li&gt;
&lt;li&gt;AOF 重写（rewrite）时会占用额外资源。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;53-混合持久化redis-40&#34;&gt;5.3 混合持久化（Redis 4.0+）&lt;/h3&gt;
&lt;p&gt;AOF 重写时先写入 RDB 全量数据，再追加增量 AOF，兼顾恢复速度和数据安全。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;aof-use-rdb-preamble yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[持久化选择] --&amp;gt; B[RDB]
    A --&amp;gt; C[AOF]
    A --&amp;gt; D[混合持久化]
    B --&amp;gt; E[适合备份/快速恢复]
    C --&amp;gt; F[适合低丢失容忍]
    D --&amp;gt; G[生产推荐]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;八股重点&lt;/strong&gt;：Redis 的持久化是「灾难恢复手段」，不是「主存储方案」。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六过期删除与内存淘汰&#34;&gt;六、过期删除与内存淘汰&lt;/h2&gt;
&lt;h3 id=&#34;61-过期删除策略&#34;&gt;6.1 过期删除策略&lt;/h3&gt;
&lt;p&gt;Redis 对过期 Key 采用两种策略结合：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;策略&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
					&lt;th&gt;优点&lt;/th&gt;
					&lt;th&gt;缺点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;惰性删除&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;访问 Key 时检查是否过期，过期则删除。&lt;/td&gt;
					&lt;td&gt;CPU 开销小&lt;/td&gt;
					&lt;td&gt;过期 Key 可能长期占用内存&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;定期删除&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;每隔一段时间随机抽查部分 Key 删除。&lt;/td&gt;
					&lt;td&gt;平衡内存与 CPU&lt;/td&gt;
					&lt;td&gt;仍可能有漏网之鱼&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;62-内存淘汰策略&#34;&gt;6.2 内存淘汰策略&lt;/h3&gt;
&lt;p&gt;当内存达到 &lt;code&gt;maxmemory&lt;/code&gt; 时，根据 &lt;code&gt;maxmemory-policy&lt;/code&gt; 决定如何淘汰：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;策略&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;noeviction&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;不淘汰，写操作直接报错。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;allkeys-lru&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;所有 Key 中淘汰最近最少使用。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;volatile-lru&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;只在设置了 TTL 的 Key 中淘汰最近最少使用。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;allkeys-random&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;所有 Key 中随机淘汰。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;volatile-random&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;只在设置了 TTL 的 Key 中随机淘汰。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;volatile-ttl&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;淘汰即将过期的 Key。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;allkeys-lfu&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;所有 Key 中淘汰使用频率最低的。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;volatile-lfu&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;只在设置了 TTL 的 Key 中淘汰使用频率最低的。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;生产建议&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;必须设置 &lt;code&gt;maxmemory&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;缓存场景推荐 &lt;code&gt;allkeys-lru&lt;/code&gt; 或 &lt;code&gt;allkeys-lfu&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;有冷热区分时可用 &lt;code&gt;volatile-lru&lt;/code&gt;，但必须给 Key 设置 TTL。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;七redis-高可用架构&#34;&gt;七、Redis 高可用架构&lt;/h2&gt;
&lt;h3 id=&#34;71-主从复制replication&#34;&gt;7.1 主从复制（Replication）&lt;/h3&gt;
&lt;p&gt;一主多从，读流量分摊到从节点。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    M[Master&amp;lt;br/&amp;gt;写 + 读] --&amp;gt;|全量/增量同步| S1[Slave 1&amp;lt;br/&amp;gt;读]
    M --&amp;gt; S2[Slave 2&amp;lt;br/&amp;gt;读]
    M --&amp;gt; S3[Slave 3&amp;lt;br/&amp;gt;读]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;复制过程&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Slave 发送 &lt;code&gt;PSYNC runId offset&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;如果 runId 一致且 offset 在复制积压缓冲区中，则&lt;strong&gt;增量同步&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;否则&lt;strong&gt;全量同步&lt;/strong&gt;：Master 执行 &lt;code&gt;bgsave&lt;/code&gt; 生成 RDB，发送给 Slave。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;复制延迟问题&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主从异步复制必然存在延迟。&lt;/li&gt;
&lt;li&gt;读从库时可能读到旧数据，需要业务容忍或强制走主库。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;72-哨兵sentinel&#34;&gt;7.2 哨兵（Sentinel）&lt;/h3&gt;
&lt;p&gt;实现自动故障转移，解决主节点宕机问题。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TB
    subgraph Sentinel 集群
        Se1[Sentinel 1]
        Se2[Sentinel 2]
        Se3[Sentinel 3]
    end
    M[Master] --&amp;gt; S1[Slave 1]
    M --&amp;gt; S2[Slave 2]
    Se1 --&amp;gt;|监控| M
    Se2 --&amp;gt;|监控| M
    Se3 --&amp;gt;|监控| M
    Se1 -.-&amp;gt; Se2
    Se2 -.-&amp;gt; Se3&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;核心机制&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主观下线（SDOWN）&lt;/strong&gt;：单个 Sentinel 认为 Master 不可用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;客观下线（ODOWN）&lt;/strong&gt;：多数 Sentinel 达成一致。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Leader 选举&lt;/strong&gt;：Sentinel 之间通过 Raft 算法选举出执行故障转移的 Leader。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;故障转移&lt;/strong&gt;：选一个 Slave 提升为 Master，通知其他 Slave 和客户端。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;73-cluster-集群&#34;&gt;7.3 Cluster 集群&lt;/h3&gt;
&lt;p&gt;Redis Cluster 采用&lt;strong&gt;无中心架构&lt;/strong&gt;，数据按槽位分布。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TB
    subgraph Redis Cluster
        N1[Node 1&amp;lt;br/&amp;gt;0-5460]
        N2[Node 2&amp;lt;br/&amp;gt;5461-10922]
        N3[Node 3&amp;lt;br/&amp;gt;10923-16383]
    end
    N1 &amp;lt;--&amp;gt; N2
    N2 &amp;lt;--&amp;gt; N3
    N1 &amp;lt;--&amp;gt; N3&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;关键概念&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;集群共有 &lt;strong&gt;16384 个槽（slot）&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;每个 Key 通过 &lt;code&gt;CRC16(key) % 16384&lt;/code&gt; 计算所属槽。&lt;/li&gt;
&lt;li&gt;每个 Master 负责一部分槽，可配置 Slave 做高可用。&lt;/li&gt;
&lt;li&gt;客户端访问错误节点时，会收到 &lt;code&gt;MOVED&lt;/code&gt; 或 &lt;code&gt;ASK&lt;/code&gt; 重定向。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;MOVED vs ASK&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MOVED&lt;/strong&gt;：槽已经永久迁移到目标节点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ASK&lt;/strong&gt;：槽正在迁移中，先访问目标节点一次。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;八事务与-lua-脚本&#34;&gt;八、事务与 Lua 脚本&lt;/h2&gt;
&lt;h3 id=&#34;81-事务multiexecdiscardwatch&#34;&gt;8.1 事务（MULTI/EXEC/DISCARD/WATCH）&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MULTI
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SET a &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;INCR b
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EXEC&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;命令按顺序入队，EXEC 时一次性执行。&lt;/li&gt;
&lt;li&gt;执行期间不会被其他客户端打断。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;但没有回滚机制&lt;/strong&gt;：如果某条命令语法错误，整个事务不执行；如果运行时错误（如 INCR 字符串），后续命令仍会执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;82-lua-脚本&#34;&gt;8.2 Lua 脚本&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;EVAL &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;return redis.call(&amp;#39;incr&amp;#39;, KEYS[1])&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; counter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;特点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;整个脚本作为一个整体在单线程中原子执行。&lt;/li&gt;
&lt;li&gt;适用于需要多个命令且要保证原子性的场景，如秒杀、分布式锁、限流。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;集群模式下所有 Key 必须落在同一 slot&lt;/strong&gt;，否则需要加 hash tag，如 &lt;code&gt;{user}:1001:profile&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;九缓存经典问题&#34;&gt;九、缓存经典问题&lt;/h2&gt;
&lt;h3 id=&#34;91-缓存穿透&#34;&gt;9.1 缓存穿透&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：查询不存在的数据，缓存不命中，请求直接打到数据库。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解法&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;缓存空值（设置短 TTL）。&lt;/li&gt;
&lt;li&gt;使用布隆过滤器预先判断 Key 是否存在。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;92-缓存击穿&#34;&gt;9.2 缓存击穿&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：热点 Key 突然过期，大量请求同时打到数据库。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解法&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;热点 Key 设置永不过期，异步更新。&lt;/li&gt;
&lt;li&gt;加互斥锁（SETNX），只允许一个线程重建缓存。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;93-缓存雪崩&#34;&gt;9.3 缓存雪崩&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：大量 Key 同时过期，或 Redis 宕机，数据库压力陡增。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解法&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;给 TTL 加随机值，避免同时失效。&lt;/li&gt;
&lt;li&gt;多级缓存（本地 + Redis）。&lt;/li&gt;
&lt;li&gt;熔断降级。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;94-缓存与数据库一致性&#34;&gt;9.4 缓存与数据库一致性&lt;/h3&gt;
&lt;p&gt;常见策略：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;策略&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
					&lt;th&gt;问题&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Cache Aside&lt;/td&gt;
					&lt;td&gt;读：先读缓存，未命中读 DB 并写回缓存；写：先更新 DB，再删缓存。&lt;/td&gt;
					&lt;td&gt;短暂不一致&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Read/Write Through&lt;/td&gt;
					&lt;td&gt;由缓存层统一维护 DB 和缓存。&lt;/td&gt;
					&lt;td&gt;实现复杂&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Write Behind&lt;/td&gt;
					&lt;td&gt;先写缓存，异步写 DB。&lt;/td&gt;
					&lt;td&gt;可能丢数据&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;最常用的是 Cache Aside&lt;/strong&gt;，配合「先更新数据库，再删除缓存」+ 延时双删 + 消息队列补偿，能在大多数场景下保证最终一致。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十redis-在-iptv-系统中的角色&#34;&gt;十、Redis 在 IPTV 系统中的角色&lt;/h2&gt;
&lt;p&gt;IPTV 系统的特点是：&lt;strong&gt;高并发读、强实时性、热点集中、写流量脉冲式&lt;/strong&gt;。用户在换台、看 EPG、播放点播、抢购付费节目时，系统需要在毫秒级返回结果。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TB
    subgraph 用户层
        A[机顶盒 / 手机 / Web]
    end

    subgraph 接入层
        B[CDN / 边缘节点]
        C[API Gateway]
    end

    subgraph 应用层
        D[鉴权服务]
        E[EPG 服务]
        F[播放调度服务]
        G[订单 / 秒杀服务]
    end

    subgraph 数据层
        H[(MySQL / 长视频元信息)]
        I[(对象存储 OSS)]
        J[(Redis 缓存 + 实时计算)]
    end

    A --&amp;gt; B --&amp;gt; C
    C --&amp;gt; D &amp;amp; E &amp;amp; F &amp;amp; G
    D --&amp;gt; J
    E --&amp;gt; J
    F --&amp;gt; J
    G --&amp;gt; J
    E --&amp;gt; H
    F --&amp;gt; I
    G --&amp;gt; H
    J -.-&amp;gt; H&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;场景&lt;/th&gt;
					&lt;th&gt;Redis 数据结构&lt;/th&gt;
					&lt;th&gt;作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;用户会话 / Token&lt;/td&gt;
					&lt;td&gt;String + EXPIRE&lt;/td&gt;
					&lt;td&gt;毫秒级鉴权&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;EPG 节目单缓存&lt;/td&gt;
					&lt;td&gt;Hash / JSON String&lt;/td&gt;
					&lt;td&gt;减少数据库查询&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;热播榜单 / 推荐位&lt;/td&gt;
					&lt;td&gt;Sorted Set (ZSET)&lt;/td&gt;
					&lt;td&gt;实时排序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;播放限速 / 防刷&lt;/td&gt;
					&lt;td&gt;Lua + INCR + EXPIRE&lt;/td&gt;
					&lt;td&gt;滑动窗口限流&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;秒杀 / 付费解锁&lt;/td&gt;
					&lt;td&gt;SETNX + DECR + Lua&lt;/td&gt;
					&lt;td&gt;库存扣减&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;消息通知 / 任务队列&lt;/td&gt;
					&lt;td&gt;List / Stream&lt;/td&gt;
					&lt;td&gt;异步解耦&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十一iptv-项目-demo&#34;&gt;十一、IPTV 项目 Demo&lt;/h2&gt;
&lt;h3 id=&#34;111-用户会话缓存&#34;&gt;11.1 用户会话缓存&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; redis
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; uuid
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; time
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; redis&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Redis(host&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;, port&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;6379&lt;/span&gt;, db&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, decode_responses&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;login&lt;/span&gt;(user_id: str, device_id: str, ttl: int &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3600&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; str:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    token &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; str(uuid&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;uuid4())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;session:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;token&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hset(key, mapping&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;: user_id,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;device_id&amp;#34;&lt;/span&gt;: device_id,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;login_at&amp;#34;&lt;/span&gt;: str(time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;time())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;expire(key, ttl)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; token
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;auth&lt;/span&gt;(token: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; dict &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hgetall(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;session:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;token&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;112-epg-节目单缓存&#34;&gt;11.2 EPG 节目单缓存&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; json
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; datetime &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; datetime
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;cache_epg&lt;/span&gt;(channel_id: str, programs: list[dict]):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;epg:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;channel_id&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;today()&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strftime(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;%Y%m&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pipe &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pipeline()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; p &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; programs:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pipe&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hset(key, p[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;start_time&amp;#39;&lt;/span&gt;], json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps(p))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pipe&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;expire(key, &lt;span style=&#34;color:#ae81ff&#34;&gt;86400&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pipe&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;execute()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_program&lt;/span&gt;(channel_id: str, start_time: str) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; dict &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hget(&lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;epg:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;channel_id&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;datetime&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;today()&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;strftime(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;%Y%m&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%d&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&lt;/span&gt;)&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, start_time)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;loads(data) &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; data &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;113-热播排行榜&#34;&gt;11.3 热播排行榜&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;record_view&lt;/span&gt;(program_id: str, score: float &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1.0&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;zincrby(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hot:tv:daily&amp;#34;&lt;/span&gt;, score, program_id)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;top_n&lt;/span&gt;(n: int &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; list[tuple[str, float]]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;zrevrange(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hot:tv:daily&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, n &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, withscores&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;114-滑动窗口限流&#34;&gt;11.4 滑动窗口限流&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LIMIT_SCRIPT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local key = KEYS[1]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local window = tonumber(ARGV[1])
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local limit = tonumber(ARGV[2])
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local now = tonumber(ARGV[3])
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local min = now - window
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;redis.call(&amp;#39;zremrangebyscore&amp;#39;, key, &amp;#39;-inf&amp;#39;, min)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local count = redis.call(&amp;#39;zcard&amp;#39;, key)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;if count &amp;lt; limit then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    redis.call(&amp;#39;zadd&amp;#39;, key, now, now)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    redis.call(&amp;#39;expire&amp;#39;, key, math.ceil(window / 1000))
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    return 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    return 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;limiter &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;register_script(LIMIT_SCRIPT)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;allow&lt;/span&gt;(user_id: str, max_qps: int &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;, window_ms: int &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; bool:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rate_limit:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;user_id&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    now &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; int(time&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;time() &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; bool(limiter(keys&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;[key], args&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;[window_ms, max_qps, now]))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;115-秒杀--限时解锁&#34;&gt;11.5 秒杀 / 限时解锁&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SECKILL_SCRIPT &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local key = KEYS[1]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local user_id = ARGV[1]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;local stock = tonumber(redis.call(&amp;#39;get&amp;#39;, key) or &amp;#39;0&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;if stock &amp;lt;= 0 then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    return -1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;if redis.call(&amp;#39;sismember&amp;#39;, key .. &amp;#39;:users&amp;#39;, user_id) == 1 then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    return 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;redis.call(&amp;#39;decr&amp;#39;, key)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;redis.call(&amp;#39;sadd&amp;#39;, key .. &amp;#39;:users&amp;#39;, user_id)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;return 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;seckill &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;register_script(SECKILL_SCRIPT)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;try_buy&lt;/span&gt;(activity_id: str, user_id: str, total_stock: int) &lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt; int:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;seckill:&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;{&lt;/span&gt;activity_id&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;:stock&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;setnx(key, total_stock)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; int(seckill(keys&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;[key], args&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;[user_id]))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;十二为什么-redis-不适合做长期存储&#34;&gt;十二、为什么 Redis 不适合做长期存储？&lt;/h2&gt;
&lt;h3 id=&#34;121-持久化不是主存储&#34;&gt;12.1 持久化不是主存储&lt;/h3&gt;
&lt;p&gt;RDB 会丢数据，AOF 文件大且恢复慢。Redis 的持久化定位是「灾难恢复」，不是「可靠主存」。&lt;/p&gt;
&lt;h3 id=&#34;122-内存成本过高&#34;&gt;12.2 内存成本过高&lt;/h3&gt;
&lt;p&gt;内存价格是 SSD 的 10-50 倍。IPTV 的媒资、播放记录、订单流水动辄几十 TB，全放 Redis 不现实。&lt;/p&gt;
&lt;h3 id=&#34;123-单线程执行风险&#34;&gt;12.3 单线程执行风险&lt;/h3&gt;
&lt;p&gt;大数据集下，一个 &lt;code&gt;KEYS *&lt;/code&gt;、&lt;code&gt;HGETALL&lt;/code&gt; 或慢查询可能阻塞整个实例。&lt;/p&gt;
&lt;h3 id=&#34;124-缺乏复杂查询能力&#34;&gt;12.4 缺乏复杂查询能力&lt;/h3&gt;
&lt;p&gt;Redis 不支持 SQL、JOIN、二级索引。长期业务数据需要分析统计时，应使用 MySQL / PostgreSQL / ClickHouse。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;结论&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Redis 适合「热数据 + 临时状态 + 实时计算」，价值在于速度；长期存储应交给磁盘数据库 + 对象存储。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十三redis-容易踩坑的地方&#34;&gt;十三、Redis 容易踩坑的地方&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;坑&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
					&lt;th&gt;解法&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;大 Key&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;String &amp;gt; 10MB，集合元素百万级&lt;/td&gt;
					&lt;td&gt;拆分、分片、UNLINK 异步删除&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;热 Key&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;单个 Key 被高频访问&lt;/td&gt;
					&lt;td&gt;本地缓存、Key 分片、Cluster&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;缓存穿透/击穿/雪崩&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;缓存失效导致 DB 被打挂&lt;/td&gt;
					&lt;td&gt;布隆过滤器、互斥锁、随机 TTL&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;未设置 maxmemory&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;内存打满后写操作报错&lt;/td&gt;
					&lt;td&gt;设置 maxmemory 和淘汰策略&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;误用 KEYS&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;KEYS *&lt;/code&gt; 扫描全库阻塞主线程&lt;/td&gt;
					&lt;td&gt;生产禁用，改用 SCAN&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Lua 跨 slot&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Cluster 下脚本 Key 不在同一 slot&lt;/td&gt;
					&lt;td&gt;使用 hash tag &lt;code&gt;{user}:1001:xxx&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;事务没有回滚&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;EXEC 后某命令失败不会撤销前面命令&lt;/td&gt;
					&lt;td&gt;业务层保证幂等，或用 Lua&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;主从延迟&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;读从库可能读到旧数据&lt;/td&gt;
					&lt;td&gt;对一致性要求高的读走主库&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十四redis-做消息队列的方法&#34;&gt;十四、Redis 做消息队列的方法&lt;/h2&gt;
&lt;h3 id=&#34;141-list轻量队列&#34;&gt;14.1 List：轻量队列&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    P[Producer] --&amp;gt;|LPUSH queue:transcode task| R[(Redis List)]
    C[Consumer] --&amp;gt;|BRPOP queue:transcode 5| R
    C --&amp;gt; S[执行转码]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;lpush(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;queue:transcode&amp;#34;&lt;/span&gt;, json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps({&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;video_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;v123&amp;#34;&lt;/span&gt;}))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;_, task &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;brpop(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;queue:transcode&amp;#34;&lt;/span&gt;, timeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：简单、阻塞读。
&lt;strong&gt;缺点&lt;/strong&gt;：无 ACK、无多消费者组、无消息回溯。&lt;/p&gt;
&lt;h3 id=&#34;142-pubsub实时广播&#34;&gt;14.2 Pub/Sub：实时广播&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;publish(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;live:start&amp;#34;&lt;/span&gt;, json&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dumps({&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;channel_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cctv1&amp;#34;&lt;/span&gt;}))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：实时、多订阅者。
&lt;strong&gt;缺点&lt;/strong&gt;：不持久化，消费者断线期间消息丢失。&lt;/p&gt;
&lt;h3 id=&#34;143-stream生产级队列&#34;&gt;14.3 Stream：生产级队列&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;xadd(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mq:events&amp;#34;&lt;/span&gt;, {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;event&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;video:play&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;u10086&amp;#34;&lt;/span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;xgroup_create(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mq:events&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;group_log&amp;#34;&lt;/span&gt;, id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;, mkstream&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;messages &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;xreadgroup(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    groupname&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;group_log&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    consumername&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;worker_1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    streams&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mq:events&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;gt;&amp;#34;&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    count&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    block&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; stream, entries &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; messages:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; msg_id, fields &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; entries:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        process(fields)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        r&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;xack(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mq:events&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;group_log&amp;#34;&lt;/span&gt;, msg_id)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：支持消费者组、ACK、消息回溯。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方式&lt;/th&gt;
					&lt;th&gt;推荐场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;List&lt;/td&gt;
					&lt;td&gt;简单任务队列&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pub/Sub&lt;/td&gt;
					&lt;td&gt;实时广播&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Stream&lt;/td&gt;
					&lt;td&gt;生产级消息队列&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十五总结&#34;&gt;十五、总结&lt;/h2&gt;
&lt;p&gt;《Redis in Action》的核心思想可以概括为一句话：&lt;strong&gt;把 Redis 当成内存里的数据结构工具箱，而不是数据库&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Redis 适合&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;缓存加速（会话、配置、热点数据）。&lt;/li&gt;
&lt;li&gt;实时计算（排行榜、计数器、限流、秒杀）。&lt;/li&gt;
&lt;li&gt;异步解耦（List / Pub/Sub / Stream）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Redis 不适合&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;长期持久化存储。&lt;/li&gt;
&lt;li&gt;复杂查询与大数据分析。&lt;/li&gt;
&lt;li&gt;超大数据集主存储。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;避免踩坑的关键是：&lt;strong&gt;控制 Key 大小、设置合理 TTL、配置淘汰策略、慎用阻塞命令、理解持久化边界&lt;/strong&gt;。Redis 用好了是神兵利器，用错了就是生产事故的导火索。&lt;/p&gt;
</description>
    </item>
    <item>
      <title>JVM 内功修炼：运行时数据区、GC 演进与现代调优实践</title>
      <link>https://ftmao.com/blog/posts/jvm-internals-guide/</link>
      <pubDate>Wed, 28 Mar 2018 14:00:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/posts/jvm-internals-guide/</guid>
      <description>&lt;h1 id=&#34;jvm-内功修炼运行时数据区gc-演进与现代调优实践&#34;&gt;JVM 内功修炼：运行时数据区、GC 演进与现代调优实践&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;JVM 是 Java 程序员逃不掉的「操作系统」。懂它不是为了背八股，而是为了在 OOM、Full GC、CPU 飙升时，能一眼定位根因并给出调优方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一高层次思想jvm-在帮你解决什么问题&#34;&gt;一、高层次思想：JVM 在帮你解决什么问题？&lt;/h2&gt;
&lt;p&gt;JVM 的核心职责可以抽象成三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;一次编译，到处运行&lt;/strong&gt;：通过字节码 + 解释/编译执行，屏蔽底层 OS 与硬件差异。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动内存管理&lt;/strong&gt;：让开发者专注于业务，而不是像 C/C++ 那样手动 malloc/free。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运行时优化&lt;/strong&gt;：JIT 编译、逃逸分析、内联、锁消除等，把「解释执行」慢慢优化成「本地机器码执行」。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[.java 源码] --&amp;gt;|javac| B[字节码 .class]
    B --&amp;gt;|类加载子系统| C[方法区/Metaspace]
    C --&amp;gt;|解释器| D[逐行解释执行]
    C --&amp;gt;|JIT 编译器| E[本地机器码]
    D --&amp;gt; F[执行引擎]
    E --&amp;gt; F
    F --&amp;gt; G[操作系统]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #1&lt;/strong&gt;：不要只把 JVM 当「黑盒」。线上 90% 的 Java 性能问题，根源都在堆外内存泄漏、GC 停顿过长、Metaspace 膨胀、线程栈溢出这四类。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二运行时数据区新版-jdk-的版图&#34;&gt;二、运行时数据区：新版 JDK 的版图&lt;/h2&gt;
&lt;p&gt;不同虚拟机的运行时数据区实现略有差异，但都遵循《Java 虚拟机规范》。现代视角下，区域可划分为「线程私有」和「线程共享」两类：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
    subgraph 线程私有
        A[程序计数器 PC Register]
        B[虚拟机栈 JVM Stack]
        C[本地方法栈 Native Method Stack]
    end
    subgraph 线程共享
        D[堆 Heap]
        E[方法区 Method Area / Metaspace]
        F[直接内存 Direct Memory]
    end
    A --&amp;gt; G[线程执行上下文]
    B --&amp;gt; G
    C --&amp;gt; G
    D --&amp;gt; H[几乎所有对象实例]
    E --&amp;gt; I[类元数据/常量/静态变量]
    F --&amp;gt; J[NIO / 堆外内存]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;21-程序计数器program-counter-register&#34;&gt;2.1 程序计数器（Program Counter Register）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;当前线程执行字节码的&lt;strong&gt;行号指示器&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;分支、循环、跳转、异常处理、线程恢复都依赖它。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;线程私有&lt;/strong&gt;，生命周期与线程一致。&lt;/li&gt;
&lt;li&gt;唯一一个在《Java 虚拟机规范》中&lt;strong&gt;没有规定 OOM&lt;/strong&gt; 的区域。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;22-java-虚拟机栈jvm-stack&#34;&gt;2.2 Java 虚拟机栈（JVM Stack）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;每个方法执行时创建一个&lt;strong&gt;栈帧&lt;/strong&gt;（Stack Frame）。&lt;/li&gt;
&lt;li&gt;栈帧里包含：局部变量表、操作数栈、动态链接、方法返回地址。&lt;/li&gt;
&lt;li&gt;局部变量表中的基本数据类型和对象引用在编译期大小就确定。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
    A[JVM Stack] --&amp;gt; B[栈帧 Frame 1]
    A --&amp;gt; C[栈帧 Frame 2]
    A --&amp;gt; D[栈帧 Frame 3]
    B --&amp;gt; B1[局部变量表]
    B --&amp;gt; B2[操作数栈]
    B --&amp;gt; B3[动态链接]
    B --&amp;gt; B4[方法返回地址]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #2&lt;/strong&gt;：&lt;code&gt;-Xss&lt;/code&gt; 设置线程栈大小。递归过深、方法调用链过长会抛出 &lt;code&gt;StackOverflowError&lt;/code&gt;；如果线程创建太多，总栈空间超过限制，会抛出 &lt;code&gt;OutOfMemoryError: unable to create new native thread&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;23-本地方法栈native-method-stack&#34;&gt;2.3 本地方法栈（Native Method Stack）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;与虚拟机栈作用相同，只是为 Native 方法服务。&lt;/li&gt;
&lt;li&gt;HotSpot 中把虚拟机栈和本地方法栈合二为一了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;24-java-堆java-heap&#34;&gt;2.4 Java 堆（Java Heap）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JVM 管理的&lt;strong&gt;最大一块内存&lt;/strong&gt;，被所有线程共享。&lt;/li&gt;
&lt;li&gt;几乎所有对象实例和数组都在这里分配。&lt;/li&gt;
&lt;li&gt;现代 GC 基本都采用&lt;strong&gt;分代收集&lt;/strong&gt;，逻辑上分为新生代、老年代。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[Java Heap] --&amp;gt; B[Young Generation 新生代]
    A --&amp;gt; C[Old Generation 老年代]
    B --&amp;gt; D[Eden 区]
    B --&amp;gt; E[Survivor From]
    B --&amp;gt; F[Survivor To]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #3&lt;/strong&gt;：不要把「堆」和「栈」对立记忆。对象在堆里，引用在栈里；但 HotSpot 的&lt;strong&gt;逃逸分析 + 标量替换&lt;/strong&gt;会把未逃逸的小对象直接分配在栈上，减轻 GC 压力。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;25-方法区method-area与-metaspace&#34;&gt;2.5 方法区（Method Area）与 Metaspace&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;存储类信息、常量、静态变量、JIT 编译后的代码缓存。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JDK 7 之前&lt;/strong&gt;：方法区在 PermGen（永久代）中，大小固定，&lt;code&gt;-XX:MaxPermSize&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JDK 8 及以后&lt;/strong&gt;：PermGen 被移除，方法区使用本地内存中的 &lt;strong&gt;Metaspace&lt;/strong&gt;，默认只受限于系统内存，用 &lt;code&gt;-XX:MaxMetaspaceSize&lt;/code&gt; 控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;版本&lt;/th&gt;
					&lt;th&gt;实现&lt;/th&gt;
					&lt;th&gt;配置参数&lt;/th&gt;
					&lt;th&gt;常见问题&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;JDK 7-&lt;/td&gt;
					&lt;td&gt;PermGen&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;-XX:PermSize&lt;/code&gt; / &lt;code&gt;-XX:MaxPermSize&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;动态生成类过多导致 &lt;code&gt;OutOfMemoryError: PermGen space&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;JDK 8+&lt;/td&gt;
					&lt;td&gt;Metaspace&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;-XX:MetaspaceSize&lt;/code&gt; / &lt;code&gt;-XX:MaxMetaspaceSize&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;类加载器泄漏导致 Metaspace 持续增长&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #4&lt;/strong&gt;：Metaspace 默认无上限，服务运行久了可能把容器内存撑爆。线上建议显式设置 &lt;code&gt;-XX:MaxMetaspaceSize&lt;/code&gt;，配合监控告警。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;26-直接内存direct-memory&#34;&gt;2.6 直接内存（Direct Memory）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;不属于 JVM 堆，但会被 JVM 直接使用，常见于 NIO 的 &lt;code&gt;DirectByteBuffer&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;分配和回收成本较高，但读写 I/O 时避免了堆内外内存拷贝（Zero Copy）。&lt;/li&gt;
&lt;li&gt;默认大小约等于 &lt;code&gt;-Xmx&lt;/code&gt;，可用 &lt;code&gt;-XX:MaxDirectMemorySize&lt;/code&gt; 控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #5&lt;/strong&gt;：Netty、RocketMQ、Elasticsearch 等中间件大量使用堆外内存。出现 &lt;code&gt;OutOfMemoryError: Direct buffer memory&lt;/code&gt; 时，先检查是否有 &lt;code&gt;ByteBuf&lt;/code&gt; / &lt;code&gt;DirectByteBuffer&lt;/code&gt; 未释放，而不是盲目加堆内存。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三垃圾回收从算法到收集器演进&#34;&gt;三、垃圾回收：从算法到收集器演进&lt;/h2&gt;
&lt;h3 id=&#34;31-判断对象是否存活&#34;&gt;3.1 判断对象是否存活&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;引用计数法&lt;/strong&gt;：Python 用，但 Java 不用，因为解决不了循环引用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可达性分析（Reachability Analysis）&lt;/strong&gt;：从 GC Roots 出发，不可达则回收。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;常见 GC Roots：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;虚拟机栈中局部变量表引用的对象。&lt;/li&gt;
&lt;li&gt;方法区中类静态属性、常量引用的对象。&lt;/li&gt;
&lt;li&gt;本地方法栈中 JNI 引用的对象。&lt;/li&gt;
&lt;li&gt;被同步锁持有的对象。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
    A[GC Roots] --&amp;gt; B[栈帧局部变量]
    A --&amp;gt; C[静态变量]
    A --&amp;gt; D[常量]
    A --&amp;gt; E[JNI 引用]
    A --&amp;gt; F[锁持有对象]
    B --&amp;gt; G[可达对象]
    C --&amp;gt; G
    D --&amp;gt; H[不可达对象&amp;lt;br/&amp;gt;等待回收]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;32-四种基础-gc-算法&#34;&gt;3.2 四种基础 GC 算法&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;算法&lt;/th&gt;
					&lt;th&gt;思想&lt;/th&gt;
					&lt;th&gt;优点&lt;/th&gt;
					&lt;th&gt;缺点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;标记-清除&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;标记无用对象，然后清除&lt;/td&gt;
					&lt;td&gt;简单，不需要移动对象&lt;/td&gt;
					&lt;td&gt;效率低，产生内存碎片&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;复制&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;内存分两块，活着的对象复制到另一块&lt;/td&gt;
					&lt;td&gt;无碎片，回收效率高&lt;/td&gt;
					&lt;td&gt;内存利用率只有一半&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;标记-整理&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;标记后把存活对象移到一端，清理边界外&lt;/td&gt;
					&lt;td&gt;无碎片，内存利用率高&lt;/td&gt;
					&lt;td&gt;移动对象开销大&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;分代收集&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;按对象存活周期分代，不同代用不同算法&lt;/td&gt;
					&lt;td&gt;兼顾吞吐与停顿&lt;/td&gt;
					&lt;td&gt;需要维护复杂的跨代引用&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;33-经典垃圾收集器&#34;&gt;3.3 经典垃圾收集器&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;收集器&lt;/th&gt;
					&lt;th&gt;工作区域&lt;/th&gt;
					&lt;th&gt;算法&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
					&lt;th&gt;状态&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Serial&lt;/td&gt;
					&lt;td&gt;新生代&lt;/td&gt;
					&lt;td&gt;复制&lt;/td&gt;
					&lt;td&gt;单线程，简单高效&lt;/td&gt;
					&lt;td&gt;客户端模式 / 单核&lt;/td&gt;
					&lt;td&gt;可用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ParNew&lt;/td&gt;
					&lt;td&gt;新生代&lt;/td&gt;
					&lt;td&gt;复制&lt;/td&gt;
					&lt;td&gt;Serial 的多线程版&lt;/td&gt;
					&lt;td&gt;配合 CMS&lt;/td&gt;
					&lt;td&gt;随 CMS 移除&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Parallel Scavenge&lt;/td&gt;
					&lt;td&gt;新生代&lt;/td&gt;
					&lt;td&gt;复制&lt;/td&gt;
					&lt;td&gt;吞吐量优先&lt;/td&gt;
					&lt;td&gt;后台计算&lt;/td&gt;
					&lt;td&gt;可用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Serial Old&lt;/td&gt;
					&lt;td&gt;老年代&lt;/td&gt;
					&lt;td&gt;标记-整理&lt;/td&gt;
					&lt;td&gt;单线程&lt;/td&gt;
					&lt;td&gt;客户端模式&lt;/td&gt;
					&lt;td&gt;可用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Parallel Old&lt;/td&gt;
					&lt;td&gt;老年代&lt;/td&gt;
					&lt;td&gt;标记-整理&lt;/td&gt;
					&lt;td&gt;多线程吞吐量优先&lt;/td&gt;
					&lt;td&gt;后台计算&lt;/td&gt;
					&lt;td&gt;可用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CMS&lt;/td&gt;
					&lt;td&gt;老年代&lt;/td&gt;
					&lt;td&gt;标记-清除&lt;/td&gt;
					&lt;td&gt;低停顿，并发收集&lt;/td&gt;
					&lt;td&gt;互联网低延迟服务&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;JDK 14 已移除&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;G1&lt;/td&gt;
					&lt;td&gt;整堆&lt;/td&gt;
					&lt;td&gt;标记-整理 + 复制&lt;/td&gt;
					&lt;td&gt;可控停顿， region 化&lt;/td&gt;
					&lt;td&gt;大堆、低延迟&lt;/td&gt;
					&lt;td&gt;JDK 9-22 默认&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ZGC&lt;/td&gt;
					&lt;td&gt;整堆&lt;/td&gt;
					&lt;td&gt;标记-复制/整理&lt;/td&gt;
					&lt;td&gt;亚毫秒停顿，TB 级堆&lt;/td&gt;
					&lt;td&gt;极低延迟&lt;/td&gt;
					&lt;td&gt;JDK 23+ 默认（分代）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Shenandoah&lt;/td&gt;
					&lt;td&gt;整堆&lt;/td&gt;
					&lt;td&gt;标记-复制/整理&lt;/td&gt;
					&lt;td&gt;低停顿，独立于分代&lt;/td&gt;
					&lt;td&gt;低延迟&lt;/td&gt;
					&lt;td&gt;可用，JDK 24 实验分代&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[Serial] --&amp;gt; B[ParNew]
    B --&amp;gt; C[Parallel Scavenge]
    C --&amp;gt; D[G1]
    D --&amp;gt; E[ZGC / Shenandoah]
    style E fill:#f9f,stroke:#333&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;h3 id=&#34;34-分代模型的工作流程&#34;&gt;3.4 分代模型的工作流程&lt;/h3&gt;
&lt;p&gt;新生代默认占堆的 1/3，老年代占 2/3。新生代内部 Eden:From Survivor:To Survivor 默认约为 8:1:1。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;sequenceDiagram
    participant Eden
    participant From as Survivor From
    participant To as Survivor To
    participant Old as Old Generation
    Note over Eden,Old: Minor GC 触发
    Eden-&amp;gt;&amp;gt;To: 存活对象复制到 To
    From-&amp;gt;&amp;gt;To: 存活对象复制到 To
    From-&amp;gt;&amp;gt;Old: 年龄超过阈值的对象晋升
    Note over Eden,From: 清空 Eden 和 From
    To-&amp;gt;&amp;gt;From: To 变 From，From 变 To&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #6&lt;/strong&gt;：不要把 Survivor 区看作「两个对称缓存区」。它们在一次 Minor GC 后会&lt;strong&gt;交换身份&lt;/strong&gt;，始终有一个是空的，用于下一次复制目标。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;35-g1-收集器里程碑式的设计&#34;&gt;3.5 G1 收集器：里程碑式的设计&lt;/h3&gt;
&lt;p&gt;G1（Garbage First）把堆划分为多个大小相等的 Region，每个 Region 动态扮演 Eden、Survivor 或 Old 角色。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
    A[G1 Heap Regions] --&amp;gt; B[Eden Region]
    A --&amp;gt; C[Survivor Region]
    A --&amp;gt; D[Old Region]
    A --&amp;gt; E[Humongous Region&amp;lt;br/&amp;gt;大对象]
    A --&amp;gt; F[Free Region]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;G1 的核心优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;可预测的停顿时间模型&lt;/strong&gt;：通过 &lt;code&gt;-XX:MaxGCPauseMillis&lt;/code&gt; 设定目标停顿。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;整体基于标记-整理，局部基于复制&lt;/strong&gt;：不会产生大面积内存碎片。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;回收优先级按垃圾最多的 Region 来&lt;/strong&gt;：Garbage First 名字来源。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #7&lt;/strong&gt;：G1 的 &lt;code&gt;-XX:MaxGCPauseMillis&lt;/code&gt; 不是越小越好。设得太低（如 50ms）会导致回收 Region 太少、GC 频率飙升，反而降低吞吐。通常建议 100-200ms。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;36-现代低延迟-gczgc-与-shenandoah&#34;&gt;3.6 现代低延迟 GC：ZGC 与 Shenandoah&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;ZGC&lt;/th&gt;
					&lt;th&gt;Shenandoah&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;设计目标&lt;/td&gt;
					&lt;td&gt;亚毫秒级停顿，支持 TB 级堆&lt;/td&gt;
					&lt;td&gt;低停顿，独立于分代&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;并发能力&lt;/td&gt;
					&lt;td&gt;标记、转移、重定位几乎都并发&lt;/td&gt;
					&lt;td&gt;并发标记、并发压缩&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;着色指针&lt;/td&gt;
					&lt;td&gt;使用&lt;/td&gt;
					&lt;td&gt;不使用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;分代&lt;/td&gt;
					&lt;td&gt;JDK 21 引入分代 ZGC，JDK 23 起为默认&lt;/td&gt;
					&lt;td&gt;JDK 24 引入实验性分代 Shenandoah&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;适用版本&lt;/td&gt;
					&lt;td&gt;JDK 11+（生产推荐 JDK 17+）&lt;/td&gt;
					&lt;td&gt;OpenJDK 12+&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[传统 GC&amp;lt;br/&amp;gt;Serial/Parallel/CMS/G1] --&amp;gt;|停顿目标 ms~百 ms 级| B[G1]
    B --&amp;gt;|停顿目标 &amp;lt; 10ms| C[ZGC / Shenandoah]
    C --&amp;gt;|JDK 21+| D[分代 ZGC]
    D --&amp;gt;|JDK 23+| E[分代 ZGC 默认]
    C --&amp;gt;|JDK 24+| F[分代 Shenandoah 实验]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;高性能建议 #1&lt;/strong&gt;：如果应用对延迟敏感（如金融交易、在线游戏、实时推荐），JDK 17 下优先考虑 &lt;strong&gt;G1&lt;/strong&gt;；JDK 21+ 可直接启用 &lt;strong&gt;分代 ZGC&lt;/strong&gt;（&lt;code&gt;-XX:+UseZGC -XX:+ZGenerational&lt;/code&gt;），在吞吐和延迟之间取得更好平衡；升级到 &lt;strong&gt;JDK 23+&lt;/strong&gt; 后分代 ZGC 已是默认，无需额外参数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;37-jdk-21222324-的-gc-演进大事记&#34;&gt;3.7 JDK 21/22/23/24 的 GC 演进大事记&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;JDK 版本&lt;/th&gt;
					&lt;th&gt;GC 相关变化&lt;/th&gt;
					&lt;th&gt;影响&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JDK 21&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;a href=&#34;https://openjdk.org/jeps/439&#34;&gt;JEP 439&lt;/a&gt; 正式发布&lt;strong&gt;分代 ZGC&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;默认仍是 G1，但可显式启用 &lt;code&gt;-XX:+ZGenerational&lt;/code&gt; 获得更低延迟&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JDK 22&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;a href=&#34;https://openjdk.org/jeps/423&#34;&gt;JEP 423&lt;/a&gt; G1 Region Pinning&lt;/td&gt;
					&lt;td&gt;G1 在 JNI 临界区内无需禁用 GC，降低延迟毛刺&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JDK 23&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;a href=&#34;https://openjdk.org/jeps/474&#34;&gt;JEP 474&lt;/a&gt; &lt;strong&gt;分代 ZGC 成为默认&lt;/strong&gt;；非分代 ZGC 废弃&lt;/td&gt;
					&lt;td&gt;新默认 GC 从 G1 切换到分代 ZGC，亚毫秒级停顿更易获得&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JDK 23&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;a href=&#34;https://bugs.openjdk.org/browse/JDK-8322630&#34;&gt;JDK-8322630&lt;/a&gt; ZGC 延迟优化&lt;/td&gt;
					&lt;td&gt;减少 GC 根节点扫描抖动&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JDK 24&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;a href=&#34;https://openjdk.org/jeps/490&#34;&gt;JEP 490&lt;/a&gt; 移除非分代 ZGC&lt;/td&gt;
					&lt;td&gt;简化 ZGC 维护，统一使用分代模式&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JDK 24&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;a href=&#34;https://openjdk.org/jeps/404&#34;&gt;JEP 404&lt;/a&gt; &lt;strong&gt;分代 Shenandoah（实验性）&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Shenandoah 也走向分代，未来低延迟 GC 竞争更激烈&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JDK 24&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;a href=&#34;https://openjdk.org/jeps/475&#34;&gt;JEP 475&lt;/a&gt; G1 Late Barrier Expansion&lt;/td&gt;
					&lt;td&gt;优化 G1 写屏障，提升编译和运行时性能&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;timeline
    title GC 默认与里程碑
    section JDK 8
        默认 : Parallel Scavenge + Parallel Old
    section JDK 9
        默认 : G1
    section JDK 11
        ZGC 实验性
    section JDK 15
        ZGC 生产可用
    section JDK 17
        G1 默认，ZGC/Shenandoah 成熟
    section JDK 21
        分代 ZGC 正式发布（仍非默认）
    section JDK 23
        分代 ZGC 成为默认 GC
    section JDK 24
        非分代 ZGC 移除；分代 Shenandoah 实验&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #7.5&lt;/strong&gt;：网上有说法称 &amp;ldquo;JDK 21 默认 GC 是 ZGC&amp;rdquo;，这是&lt;strong&gt;错误&lt;/strong&gt;的。JDK 21 默认仍是 &lt;strong&gt;G1&lt;/strong&gt;；分代 ZGC 只是正式发布，需要显式开启。真正的默认切换发生在 &lt;strong&gt;JDK 23&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四引用类型不只是强引用&#34;&gt;四、引用类型：不只是强引用&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;引用类型&lt;/th&gt;
					&lt;th&gt;回收时机&lt;/th&gt;
					&lt;th&gt;使用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;强引用&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;永不回收，即使 OOM&lt;/td&gt;
					&lt;td&gt;普通对象&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;软引用 SoftReference&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;内存不足前回收&lt;/td&gt;
					&lt;td&gt;缓存，如图片缓存&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;弱引用 WeakReference&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;下一次 GC 时回收&lt;/td&gt;
					&lt;td&gt;防止内存泄漏，如 &lt;code&gt;WeakHashMap&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;虚引用 PhantomReference&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;随时可能被回收，必须配合 ReferenceQueue&lt;/td&gt;
					&lt;td&gt;跟踪对象被回收的事件，做资源后置清理&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[强引用] --&amp;gt;|最强| B[不会被回收]
    C[软引用] --&amp;gt;|内存紧张| D[回收]
    E[弱引用] --&amp;gt;|下次 GC| F[回收]
    G[虚引用] --&amp;gt;|无法获取对象| H[仅回收通知]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #8&lt;/strong&gt;：不要把软引用当「万能缓存」。在内存紧张时软引用会被批量回收，导致缓存命中率骤降。高并发缓存建议用 Caffeine 等带 TTL 和淘汰策略的专业缓存框架。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;五类加载机制双亲委派与破坏&#34;&gt;五、类加载机制：双亲委派与破坏&lt;/h2&gt;
&lt;h3 id=&#34;51-类加载器层次&#34;&gt;5.1 类加载器层次&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
    A[自定义类加载器] --&amp;gt;|委托| B[应用程序类加载器 AppClassLoader]
    B --&amp;gt;|委托| C[平台类加载器 PlatformClassLoader]
    C --&amp;gt;|委托| D[启动类加载器 BootstrapClassLoader]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：JDK 9 引入模块化系统后，原来的 &lt;strong&gt;Extension ClassLoader&lt;/strong&gt; 被改名为 &lt;strong&gt;Platform ClassLoader&lt;/strong&gt;，负责加载平台模块（如 &lt;code&gt;java.sql&lt;/code&gt;、&lt;code&gt;java.xml&lt;/code&gt; 等）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;52-双亲委派模型&#34;&gt;5.2 双亲委派模型&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;类加载器收到加载请求，先不自己加载。&lt;/li&gt;
&lt;li&gt;向上委托给父加载器。&lt;/li&gt;
&lt;li&gt;父加载器无法加载时，子加载器才尝试加载。&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #9&lt;/strong&gt;：Tomcat、SPI、OSGi 都&lt;strong&gt;破坏了双亲委派&lt;/strong&gt;。如果你的项目出现 &lt;code&gt;NoSuchMethodError&lt;/code&gt; / &lt;code&gt;ClassCastException: cannot cast to the same class&lt;/code&gt;，很可能是同一个类被不同类加载器加载了两次。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;六jit-编译与执行优化&#34;&gt;六、JIT 编译与执行优化&lt;/h2&gt;
&lt;p&gt;Java 代码先被解释器执行，热点代码会被 JIT 编译成本地机器码。&lt;/p&gt;
&lt;h3 id=&#34;61-hotspot-的两层编译器&#34;&gt;6.1 HotSpot 的两层编译器&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;编译器&lt;/th&gt;
					&lt;th&gt;别称&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;C1&lt;/td&gt;
					&lt;td&gt;Client Compiler&lt;/td&gt;
					&lt;td&gt;编译快，优化简单，适合启动速度和 GUI&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;C2&lt;/td&gt;
					&lt;td&gt;Server Compiler&lt;/td&gt;
					&lt;td&gt;编译慢，激进优化，适合长期运行的服务端&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;JDK 7 引入&lt;strong&gt;分层编译&lt;/strong&gt;（Tiered Compilation），JDK 8 默认开启：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;0: 解释执行
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1~3: C1 编译，带简单/复杂优化
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4: C2 编译，激进优化&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h3 id=&#34;62-常见-jit-优化&#34;&gt;6.2 常见 JIT 优化&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;优化&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;方法内联&lt;/td&gt;
					&lt;td&gt;把短方法体直接嵌入调用处，减少栈帧开销&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;逃逸分析&lt;/td&gt;
					&lt;td&gt;判断对象是否逃出方法/线程作用域&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;标量替换&lt;/td&gt;
					&lt;td&gt;把对象拆成基本类型分配在栈上&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;锁消除&lt;/td&gt;
					&lt;td&gt;确认对象只被单线程访问时去掉同步锁&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;锁粗化&lt;/td&gt;
					&lt;td&gt;把相邻的同步块合并，减少加解锁次数&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;高性能建议 #2&lt;/strong&gt;：不要过度纠结「每个对象都在堆上分配」。现代 JVM 的逃逸分析已经很强，写代码时优先保证&lt;strong&gt;对象作用域最小化&lt;/strong&gt;、&lt;strong&gt;避免无意义的全局引用&lt;/strong&gt;，让 JIT 有优化空间。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;七现代-jvm-前沿特性jdk-21&#34;&gt;七、现代 JVM 前沿特性（JDK 21+）&lt;/h2&gt;
&lt;p&gt;除了 GC，JDK 21 及之后版本还在内存模型、执行模型和 Native 互操作上做了大量演进，这些也会间接影响 JVM 调优思路。&lt;/p&gt;
&lt;h3 id=&#34;71-虚拟线程virtual-threadsjep-444--jdk-21&#34;&gt;7.1 虚拟线程（Virtual Threads，JEP 444 / JDK 21）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;虚拟线程是 JVM 管理的轻量级线程，由 JVM 调度到少量平台线程（Carrier Thread）上运行。&lt;/li&gt;
&lt;li&gt;创建成本极低（KB 级栈），适合高并发 I/O 密集型应用。&lt;/li&gt;
&lt;li&gt;对 JVM 数据区的影响：虚拟线程的栈帧仍存在于 Java 堆中（作为 &lt;code&gt;Continuation&lt;/code&gt; 对象），而不是传统的线程栈。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[平台线程 Platform Thread] --&amp;gt;|1:N 映射| B[虚拟线程 Virtual Thread]
    B --&amp;gt;|挂载| C[Carrier Thread]
    C --&amp;gt;|运行在| D[OS 线程]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;避坑指南 #9.5&lt;/strong&gt;：虚拟线程虽好，但不要和 &lt;code&gt;synchronized&lt;/code&gt; 块、本地方法、文件 I/O 混用导致 &amp;ldquo;Pinning&amp;rdquo;，会让载体线程被卡住，降低并发收益。优先使用 &lt;code&gt;ReentrantLock&lt;/code&gt; 和异步 I/O。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;72-foreign-function--memory-apijep-454--jdk-22&#34;&gt;7.2 Foreign Function &amp;amp; Memory API（JEP 454 / JDK 22）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;正式替代 &lt;code&gt;sun.misc.Unsafe&lt;/code&gt; 进行堆外内存操作。&lt;/li&gt;
&lt;li&gt;通过 &lt;code&gt;Arena&lt;/code&gt; 管理堆外内存生命周期，更安全、更可移植。&lt;/li&gt;
&lt;li&gt;对直接内存调优的影响：未来 &lt;code&gt;DirectByteBuffer&lt;/code&gt; 的底层实现会逐步迁移到 FFM API。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;73-project-lilliput压缩对象头&#34;&gt;7.3 Project Lilliput：压缩对象头&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;目标是把 HotSpot 的对象头从 96/128 bit 压缩到 64 bit。&lt;/li&gt;
&lt;li&gt;可以显著降低内存占用，提升缓存命中率。&lt;/li&gt;
&lt;li&gt;JDK 24 起部分功能已集成（如 64-bit object headers）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;74-project-valhalla值类型value-classes--primitive-classes&#34;&gt;7.4 Project Valhalla：值类型（Value Classes / Primitive Classes）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;引入 &amp;ldquo;值对象&amp;rdquo;，避免对象头和引用开销。&lt;/li&gt;
&lt;li&gt;未来 &lt;code&gt;int[]&lt;/code&gt; 和 &lt;code&gt;Integer[]&lt;/code&gt; 之间的性能鸿沟会缩小。&lt;/li&gt;
&lt;li&gt;目前处于预览阶段，持续关注即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;75-project-leydenjava-静态镜像&#34;&gt;7.5 Project Leyden：Java 静态镜像&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;目标是通过 &amp;ldquo;静态图像&amp;rdquo; 加速 Java 启动时间。&lt;/li&gt;
&lt;li&gt;类似 GraalVM Native Image，但保持完整 Java 语义和 JVM 运行时能力。&lt;/li&gt;
&lt;li&gt;对 Serverless、CLI 工具、云原生场景意义重大。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;八避坑指南线上常见问题&#34;&gt;八、避坑指南：线上常见问题&lt;/h2&gt;
&lt;h3 id=&#34;81-慎用-systemgc&#34;&gt;8.1 慎用 &lt;code&gt;System.gc()&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;只是「建议」JVM 进行 Full GC，不保证执行。&lt;/li&gt;
&lt;li&gt;很多框架（如某些老版本 JDBC）会调用它，导致不可控停顿。&lt;/li&gt;
&lt;li&gt;线上建议关闭：&lt;code&gt;-XX:+DisableExplicitGC&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;82-finalize-已过时&#34;&gt;8.2 finalize() 已过时&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JDK 9 起标记为 &lt;code&gt;@Deprecated&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;对象回收前不保证一定执行 &lt;code&gt;finalize()&lt;/code&gt;，且执行顺序不确定。&lt;/li&gt;
&lt;li&gt;资源清理用 &lt;code&gt;try-with-resources&lt;/code&gt; 或 &lt;code&gt;Cleaner&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;83-大对象与-humongous&#34;&gt;8.3 大对象与 Humongous&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;G1 中超过 Region 大小一半的对象叫 Humongous Object，直接进老年代，增加 GC 负担。&lt;/li&gt;
&lt;li&gt;避免一次性创建超大数组或字符串。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;84-动态代理与-cglib-的-metaspace-泄漏&#34;&gt;8.4 动态代理与 CGLIB 的 Metaspace 泄漏&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Spring AOP、MyBatis、Dubbo 大量生成代理类。&lt;/li&gt;
&lt;li&gt;如果 ClassLoader 没释放，代理类元数据会持续占用 Metaspace。&lt;/li&gt;
&lt;li&gt;常见于热部署、OSGi、动态脚本场景。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;85-大堆--full-gc-的雪崩&#34;&gt;8.5 大堆 + Full GC 的雪崩&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;堆内存越大，G1 的 Mixed GC、CMS 的 Full GC 停顿越长。&lt;/li&gt;
&lt;li&gt;超过 32GB 时，指针压缩会失效，对象头变大，反而浪费内存。&lt;/li&gt;
&lt;li&gt;建议堆大小控制在 16GB-32GB 之间，再大的堆考虑横向拆分服务或换 ZGC。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;九高性能调优建议&#34;&gt;九、高性能调优建议&lt;/h2&gt;
&lt;h3 id=&#34;91-选择-gc-与-jdk-版本&#34;&gt;9.1 选择 GC 与 JDK 版本&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;场景&lt;/th&gt;
					&lt;th&gt;推荐配置&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;通用 Web 服务，JDK 17-22&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;-XX:+UseG1GC -XX:MaxGCPauseMillis=200&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;通用 Web 服务，&lt;strong&gt;JDK 23+&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;默认已是分代 ZGC，一般无需改动&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;延迟敏感，JDK 21-22&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;-XX:+UseZGC -XX:+ZGenerational&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;延迟敏感，JDK 23+&lt;/td&gt;
					&lt;td&gt;默认分代 ZGC，无需显式开启&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;批处理/大数据，吞吐优先&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;-XX:+UseParallelGC&lt;/code&gt; 或 G1&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;容器环境&lt;/td&gt;
					&lt;td&gt;显式设置 &lt;code&gt;-Xmx&lt;/code&gt;、&lt;code&gt;-Xms&lt;/code&gt;、&lt;code&gt;-XX:MaxMetaspaceSize&lt;/code&gt;，并开启 &lt;code&gt;-XX:+UseContainerSupport&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;92-参数模板&#34;&gt;9.2 参数模板&lt;/h3&gt;
&lt;h4 id=&#34;jdk-17-22-通用-web-服务g1&#34;&gt;JDK 17-22 通用 Web 服务（G1）&lt;/h4&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms4g -Xmx4g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseG1GC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxGCPauseMillis&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar app.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;h4 id=&#34;jdk-23-通用-web-服务默认分代-zgc&#34;&gt;JDK 23+ 通用 Web 服务（默认分代 ZGC）&lt;/h4&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms4g -Xmx4g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;10,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;100m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar app.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：JDK 23 起默认就是分代 ZGC，不需要 &lt;code&gt;-XX:+UseZGC&lt;/code&gt;。如果仍想显式启用，可保留；如果想用回 G1，使用 &lt;code&gt;-XX:+UseG1GC&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;93-监控与诊断三板斧&#34;&gt;9.3 监控与诊断三板斧&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;用途&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jstat -gcutil &amp;lt;pid&amp;gt; 1000&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;实时查看 GC 频率与内存占比&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jmap -dump:format=b,file=... &amp;lt;pid&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;生成堆快照，MAT 分析内存泄漏&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jstack &amp;lt;pid&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;打印线程栈，排查死锁与 CPU 热点&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GC 日志 / &lt;code&gt;-Xlog:gc*&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;分析 GC 原因与停顿时间&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;async-profiler&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;低开销 CPU/内存/锁分析&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;高性能建议 #3&lt;/strong&gt;：调优前一定先&lt;strong&gt;定目标&lt;/strong&gt;——是降低停顿？提高吞吐？还是减少内存？没有目标的调优就是瞎调。先用 GC 日志和监控找到瓶颈，再改参数，而不是反向操作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十jvm-问题排查实战发现--定位--修复&#34;&gt;十、JVM 问题排查实战：发现 → 定位 → 修复&lt;/h2&gt;
&lt;p&gt;线上 JVM 问题通常表现为：服务卡顿、响应 P99 飙高、CPU 打满、内存持续增长、频繁 OOM。解决它们的核心思路是：&lt;strong&gt;先量化，再猜测&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;101-问题发现的四层入口&#34;&gt;10.1 问题发现的四层入口&lt;/h3&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
    A[业务层] --&amp;gt;|接口超时/P99 飙升| B[应用层]
    B --&amp;gt;|Full GC 频繁/GC 时间长| C[JVM 层]
    C --&amp;gt;|堆/栈/Metaspace 异常| D[系统层]
    D --&amp;gt;|容器 OOMKilled/CPU 限流| E[基础设施层]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;入口&lt;/th&gt;
					&lt;th&gt;典型现象&lt;/th&gt;
					&lt;th&gt;常见根因&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;业务监控&lt;/td&gt;
					&lt;td&gt;接口 RT 上涨、错误率增加&lt;/td&gt;
					&lt;td&gt;GC 停顿、线程阻塞、锁竞争&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;APM / Trace&lt;/td&gt;
					&lt;td&gt;某段链路偶发耗时几百 ms&lt;/td&gt;
					&lt;td&gt;Full GC、Metaspace 扩容、类加载&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;容器监控&lt;/td&gt;
					&lt;td&gt;Pod 内存触顶被 OOMKilled&lt;/td&gt;
					&lt;td&gt;堆外内存泄漏、堆太大、Metaspace 无上限&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GC 日志&lt;/td&gt;
					&lt;td&gt;GC 频率异常、停顿时间超标&lt;/td&gt;
					&lt;td&gt;收集器选择不当、堆大小不合理、大对象过多&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;JVM 告警&lt;/td&gt;
					&lt;td&gt;Heap 使用率 &amp;gt; 85%、FGC 次数突增&lt;/td&gt;
					&lt;td&gt;内存泄漏、流量突增、缓存失控&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;102-排查工具箱&#34;&gt;10.2 排查工具箱&lt;/h3&gt;
&lt;h4 id=&#34;1021-命令行工具适合快速止血&#34;&gt;10.2.1 命令行工具（适合快速止血）&lt;/h4&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;命令&lt;/th&gt;
					&lt;th&gt;场景&lt;/th&gt;
					&lt;th&gt;输出重点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jps -lvm&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;找到 Java 进程 PID&lt;/td&gt;
					&lt;td&gt;主类名、启动参数&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jstat -gcutil &amp;lt;pid&amp;gt; 1000&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;实时监控 GC 与内存&lt;/td&gt;
					&lt;td&gt;S0/S1/E/O/M 各区使用率、YGC/FGC 次数&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jmap -heap &amp;lt;pid&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查看堆配置与概览&lt;/td&gt;
					&lt;td&gt;新生代/老年代大小、收集器&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jmap -histo &amp;lt;pid&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查看对象直方图&lt;/td&gt;
					&lt;td&gt;哪个类实例数/占用最多&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jmap -dump:format=b,file=... &amp;lt;pid&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;生成堆 dump&lt;/td&gt;
					&lt;td&gt;配合 MAT / JProfiler 分析&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jstack &amp;lt;pid&amp;gt;&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;打印线程栈&lt;/td&gt;
					&lt;td&gt;死锁、CPU 热点线程、Blocked 线程&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jcmd &amp;lt;pid&amp;gt; VM.native_memory summary&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;查看 Native Memory Tracking&lt;/td&gt;
					&lt;td&gt;堆外内存、Metaspace、Symbol 区占用&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;1022-可视化--专业工具&#34;&gt;10.2.2 可视化 / 专业工具&lt;/h4&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;工具&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
					&lt;th&gt;特点&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;MAT (Eclipse Memory Analyzer)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;分析堆 dump&lt;/td&gt;
					&lt;td&gt;大对象、内存泄漏、支配树、Leak Suspects&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;JProfiler / YourKit&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;全链路 JVM 分析&lt;/td&gt;
					&lt;td&gt;CPU、内存、线程、GC 一体化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;async-profiler&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;生产环境火焰图&lt;/td&gt;
					&lt;td&gt;低开销，适合线上持续采样&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;GCViewer / GCEasy&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;解析 GC 日志&lt;/td&gt;
					&lt;td&gt;可视化 GC 事件、停顿分布&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Prometheus + Grafana&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;长期监控与告警&lt;/td&gt;
					&lt;td&gt;自定义 JVM 指标大盘&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Arthas&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;线上实时诊断&lt;/td&gt;
					&lt;td&gt;无需重启，支持 trace、watch、thread、heapdump&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;103-典型问题排查流程&#34;&gt;10.3 典型问题排查流程&lt;/h3&gt;
&lt;h4 id=&#34;场景-1cpu-飙升&#34;&gt;场景 1：CPU 飙升&lt;/h4&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 1. 找到 CPU 占用最高的线程&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps -mp &amp;lt;pid&amp;gt; -o THREAD,tid,time | sort -rn
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 2. 把 tid 转成十六进制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;printf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%x\n&amp;#34;&lt;/span&gt; &amp;lt;tid&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 3. 用 jstack 查看对应线程栈&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jstack &amp;lt;pid&amp;gt; | grep -A &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt; &amp;lt;hex_tid&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;常见根因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;死循环或复杂正则&lt;/li&gt;
&lt;li&gt;Young GC 过于频繁&lt;/li&gt;
&lt;li&gt;JIT 编译器 C2 线程忙碌（启动期正常）&lt;/li&gt;
&lt;li&gt;大量 &lt;code&gt;ThreadLocal&lt;/code&gt; 未清理&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;场景-2内存持续增长--oom&#34;&gt;场景 2：内存持续增长 / OOM&lt;/h4&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 1. 确认哪个区域增长&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jstat -gcutil &amp;lt;pid&amp;gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 2. 开启 Native Memory Tracking&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jcmd &amp;lt;pid&amp;gt; VM.native_memory baseline
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jcmd &amp;lt;pid&amp;gt; VM.native_memory summary.diff
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 3. 触发堆 dump（若还能响应）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;jmap -dump:live,format&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;b,file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/tmp/heap.hprof &amp;lt;pid&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;常见根因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;堆：缓存无淘汰、大对象、集合只增不减&lt;/li&gt;
&lt;li&gt;Metaspace：动态代理/CGLIB 类加载器泄漏&lt;/li&gt;
&lt;li&gt;堆外：Netty &lt;code&gt;ByteBuf&lt;/code&gt; 未释放、NIO DirectBuffer 堆积&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;场景-3接口偶发卡顿--p99-高&#34;&gt;场景 3：接口偶发卡顿 / P99 高&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;打开 GC 日志，看是否有 &lt;strong&gt;长停顿&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;jstack&lt;/code&gt; 抓取卡顿时刻线程栈，看是否有大量 &lt;code&gt;BLOCKED&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;async-profiler&lt;/code&gt; 采集 CPU 火焰图，定位热点方法。&lt;/li&gt;
&lt;li&gt;检查是否有 &lt;code&gt;System.gc()&lt;/code&gt;、Metaspace 扩容、类加载抖动。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;104-jvm-监控告警建议&#34;&gt;10.4 JVM 监控告警建议&lt;/h3&gt;
&lt;p&gt;建议把以下指标接入 Prometheus + Grafana，并设置合理阈值：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;指标&lt;/th&gt;
					&lt;th&gt;告警阈值建议&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jvm_memory_used_bytes / jvm_memory_max_bytes&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&amp;gt; 85%&lt;/td&gt;
					&lt;td&gt;堆/非堆内存使用率&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jvm_gc_pause_seconds_sum&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;P99 &amp;gt; 200ms&lt;/td&gt;
					&lt;td&gt;GC 停顿时间&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jvm_gc_memory_allocated_bytes_total&lt;/code&gt; 增长率&lt;/td&gt;
					&lt;td&gt;突增 2 倍以上&lt;/td&gt;
					&lt;td&gt;对象分配速率异常&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jvm_classes_loaded_total&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;持续增长&lt;/td&gt;
					&lt;td&gt;类泄漏嫌疑&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;process_cpu_usage&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&amp;gt; 80% 持续 5min&lt;/td&gt;
					&lt;td&gt;CPU 压力&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;jvm_threads_live&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;突增或接近上限&lt;/td&gt;
					&lt;td&gt;线程泄漏&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;容器维度 &lt;code&gt;container_memory_working_set_bytes&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&amp;gt; 90% limit&lt;/td&gt;
					&lt;td&gt;容器 OOMKilled 预警&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
    A[应用埋点] --&amp;gt;|Micrometer| B[Prometheus]
    C[GC 日志] --&amp;gt;|Loki / Filebeat| D[日志平台]
    B --&amp;gt; E[Grafana 大盘]
    D --&amp;gt; E
    E --&amp;gt;|阈值触发| F[AlertManager]
    F --&amp;gt;|通知| G[钉钉/企业微信/Slack]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;十一不同场景的-jvm-配置策略&#34;&gt;十一、不同场景的 JVM 配置策略&lt;/h2&gt;
&lt;h3 id=&#34;111-配置前的通用原则&#34;&gt;11.1 配置前的通用原则&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;先压测，再调优&lt;/strong&gt;：没有真实流量数据，调参都是拍脑袋。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xms = Xmx&lt;/strong&gt;：避免运行时堆扩容带来的 GC 抖动。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metaspace 必须设上限&lt;/strong&gt;：容器环境下尤其重要。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GC 日志一定要开&lt;/strong&gt;：&lt;code&gt;-Xlog:gc*&lt;/code&gt;（JDK 9+）成本很低，信息无价。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;容器环境开启 Container Support&lt;/strong&gt;：&lt;code&gt;-XX:+UseContainerSupport&lt;/code&gt;（JDK 8u191+/10+ 默认开启）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要堆内存无限大&lt;/strong&gt;：超过 32GB 指针压缩失效，性价比骤降。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;112-场景一高并发-web--api-服务&#34;&gt;11.2 场景一：高并发 Web / API 服务&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;特征&lt;/strong&gt;：QPS 高、对象生命周期短、响应延迟敏感。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：降低 GC 停顿、控制 P99。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐配置（JDK 17-22，G1）&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms4g -Xmx4g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseG1GC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxGCPauseMillis&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:InitiatingHeapOccupancyPercent&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;35&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;10,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;100m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar app.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;推荐配置（JDK 23+，默认分代 ZGC）&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms4g -Xmx4g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;10,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;100m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar app.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;调优要点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新生代尽量大，让短生命周期对象在 Young GC 回收。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-XX:MaxGCPauseMillis&lt;/code&gt; 根据业务容忍度设置，100-200ms 常见。&lt;/li&gt;
&lt;li&gt;监控 &lt;code&gt;jvm_gc_pause_seconds_sum&lt;/code&gt;，若频繁触发 Mixed GC，考虑增大 &lt;code&gt;-XX:InitiatingHeapOccupancyPercent&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;113-场景二高流量--削峰填谷消息队列消费者&#34;&gt;11.3 场景二：高流量 / 削峰填谷（消息队列消费者）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;特征&lt;/strong&gt;：突发流量、消息处理批量化、吞吐优先、允许一定延迟。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：提高吞吐，避免 OOM 和 Full GC。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐配置&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms8g -Xmx8g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseG1GC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxGCPauseMillis&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;300&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:G1HeapRegionSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;16m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:InitiatingHeapOccupancyPercent&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;10,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;100m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar consumer.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;调优要点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;堆可以比 Web 服务稍大，因为要缓冲突发消息。&lt;/li&gt;
&lt;li&gt;批量消费时注意控制单次拉取消息数，避免一次创建过多对象。&lt;/li&gt;
&lt;li&gt;如果业务允许更高延迟，可考虑 &lt;code&gt;-XX:+UseParallelGC&lt;/code&gt; 追求极致吞吐。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;114-场景三低延迟金融--交易--实时推荐&#34;&gt;11.4 场景三：低延迟金融 / 交易 / 实时推荐&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;特征&lt;/strong&gt;：P99 要求 &amp;lt; 10ms，任何 GC 停顿都可能导致业务损失。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：亚毫秒级 GC 停顿。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐配置（JDK 21+）&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms16g -Xmx16g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseZGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+ZGenerational &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;10,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;100m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar trading.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;JDK 23+ 可简化为&lt;/strong&gt;（默认就是分代 ZGC）：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms16g -Xmx16g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;10,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;100m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar trading.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;调优要点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;堆 &amp;gt; 16GB 时 ZGC 优势更明显。&lt;/li&gt;
&lt;li&gt;避免大对象（Humongous），ZGC 对大对象分配路径不如小对象高效。&lt;/li&gt;
&lt;li&gt;监控 &lt;code&gt;jvm_gc_pause_seconds_max&lt;/code&gt;，正常应在 1ms 以内。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;115-场景四大数据--批处理--etl&#34;&gt;11.5 场景四：大数据 / 批处理 / ETL&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;特征&lt;/strong&gt;：长时间运行、对象存活久、吞吐优先、延迟不敏感。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：最大化吞吐，减少总 GC 时间。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐配置&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms16g -Xmx16g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;1g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseParallelGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:ParallelGCThreads&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseLargePages &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;10,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;100m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar etl.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;调优要点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Parallel GC 在纯吞吐场景下通常优于 G1。&lt;/li&gt;
&lt;li&gt;大堆 + 大页（LargePages）减少 TLB miss。&lt;/li&gt;
&lt;li&gt;如果批处理任务会频繁 Full GC，考虑分阶段释放引用或使用堆外缓存。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;116-场景五容器--k8s-微服务&#34;&gt;11.6 场景五：容器 / K8s 微服务&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;特征&lt;/strong&gt;：资源受限、弹性伸缩、多实例共享节点。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：稳定、不 OOMKilled、启动快。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐配置&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseContainerSupport &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:InitialRAMPercentage&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;70.0 &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxRAMPercentage&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;70.0 &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;128m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseG1GC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxGCPauseMillis&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xlog:gc*:file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/gc.log:time,uptime,level,tags:filecount&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;5,filesize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;50m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar service.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;调优要点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用 &lt;code&gt;-XX:MaxRAMPercentage&lt;/code&gt; 替代固定 &lt;code&gt;-Xmx&lt;/code&gt;，适配不同 Limit。&lt;/li&gt;
&lt;li&gt;容器 memory limit 要预留 10%-20% 给堆外内存、Metaspace、线程栈、JVM 自身。&lt;/li&gt;
&lt;li&gt;不要把 &lt;code&gt;-Xmx&lt;/code&gt; 设成容器 limit 的 100%，否则容易被 OOMKilled。&lt;/li&gt;
&lt;li&gt;JDK 23+ 在容器里可直接用默认分代 ZGC。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;117-场景六spring-boot--微服务网关&#34;&gt;11.7 场景六：Spring Boot / 微服务网关&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;特征&lt;/strong&gt;：启动时大量类加载、反射多、动态代理多。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目标&lt;/strong&gt;：启动快 + 运行稳。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;推荐配置&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;java &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Xms2g -Xmx2g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;256m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxMetaspaceSize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;512m &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+UseG1GC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:MaxGCPauseMillis&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;150&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+AlwaysPreTouch &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+DisableExplicitGC &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:+HeapDumpOnOutOfMemoryError &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -XX:HeapDumpPath&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/log/app/heapdump.hprof &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -Dspring.backgroundpreinitializer.ignore&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;true &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  -jar gateway.jar&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;p&gt;&lt;strong&gt;调优要点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spring Boot 启动时 Metaspace 会快速上涨，初始值不要设太小。&lt;/li&gt;
&lt;li&gt;如果启动慢，可用 &lt;code&gt;-XX:+TieredCompilation&lt;/code&gt; 配合 &lt;code&gt;-XX:TieredStopAtLevel=1&lt;/code&gt; 加速启动（牺牲峰值性能）。&lt;/li&gt;
&lt;li&gt;网关避免在请求路径创建大对象，优先复用对象和缓冲区。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;十二一句话总结&#34;&gt;十二、一句话总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内存&lt;/strong&gt;：堆内分代、堆外 Direct、Metaspace 存类元数据；虚拟线程栈帧在堆中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GC&lt;/strong&gt;：Serial → Parallel → CMS → G1 → &lt;strong&gt;分代 ZGC&lt;/strong&gt;；JDK 21 分代 ZGC 正式发布，&lt;strong&gt;JDK 23 起成为默认 GC&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;引用&lt;/strong&gt;：强 &amp;gt; 软 &amp;gt; 弱 &amp;gt; 虚，缓存别滥用软引用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能&lt;/strong&gt;：JDK 17-22 优先 G1；JDK 23+ 默认分代 ZGC；延迟极致用 ZGC，吞吐优先用 Parallel。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排查&lt;/strong&gt;：监控先行 → 日志定位 → 工具分析 → 压测验证 → 持续观察。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;场景&lt;/strong&gt;：Web 服务控延迟、消息队列保吞吐、金融交易用 ZGC、批处理用 Parallel、容器环境留余量。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;JVM 调优没有银弹，但有方法论：&lt;strong&gt;理解数据区 → 选对收集器 → 设定合理目标 → 用日志验证 → 持续监控&lt;/strong&gt;。把这套流程跑熟，面试八股和线上救火就都不慌了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;参考&#34;&gt;参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;《深入理解 Java 虚拟机》（第三版）周志明&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.oracle.com/en/java/javase/21/gctuning/&#34;&gt;OpenJDK HotSpot Virtual Machine Garbage Collection Tuning Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openjdk.org/jeps/333&#34;&gt;JEP 333: ZGC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openjdk.org/jeps/439&#34;&gt;JEP 439: Generational ZGC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openjdk.org/jeps/474&#34;&gt;JEP 474: ZGC Generational Mode by Default&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openjdk.org/jeps/490&#34;&gt;JEP 490: Remove the Non-Generational ZGC Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openjdk.org/jeps/404&#34;&gt;JEP 404: Generational Shenandoah (Experimental)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openjdk.org/jeps/444&#34;&gt;JEP 444: Virtual Threads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openjdk.org/jeps/454&#34;&gt;JEP 454: Foreign Function &amp;amp; Memory API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openjdk.org/projects/lilliput/&#34;&gt;Project Lilliput&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
