# online-problem **Repository Path**: leeos/online-problem ## Basic Information - **Project Name**: online-problem - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-02 - **Last Updated**: 2026-09-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Java 线上故障模拟演练项目 > 给开发 / 测试 / 运维同学练习**线上高频问题排查**的沙盒项目。 > 纯原生 Java(JDK8+/JDK17 均可)、无 Spring、零第三方依赖,`main` 方法一键复现。 覆盖 6 大核心线上问题,每个场景都配套:**故障原理(类头注释)+ 复现代码 + JVM 启动参数 + 排查步骤 + 解决方案**。 ## 快速开始 ```bash ./scripts/compile.sh # 编译(或直接用 run.sh,会自动编译) ./run.sh # 交互式菜单:选大类 → 选场景 → 跑起来 → 另开终端排查 # 或直接进某个大类: ./run.sh cpu | oom | thread | gc | leak ``` 要求:JDK 8 及以上(本机有 JDK8~JDK17 均可)。排查工具用 JDK 自带 `jstack / jmap / jstat / jcmd / jhsdb`,可选装 Arthas。 > 大部分故障会**一直运行**,复现后按 `Ctrl+C` 结束即可。OOM 类大多自带「保留现场」逻辑,方便边跑边 `jmap`。 ## 目录结构 ``` src/main/java/com/demo/online/problem ├── cpu/CpuFullDemo.java # CPU 100%:死循环/正则回溯/MD5/字符串拼接/排序 ├── oom/HeapOomDemo.java # 堆溢出(heap) + GC overhead + 超大对象(huge) + 缓慢泄漏(slow) ├── oom/StackOomDemo.java # 栈溢出(sof/deep/json) + 创建线程 OOM(thread) ├── oom/MetaspaceOomDemo.java # 元空间溢出:动态代理(proxy)/lambda/lambda 元工厂/动态编译(compile) ├── oom/DirectMemoryOomDemo.java # 直接内存溢出:direct/nofree/unsafe/mmap ├── thread/DeadLockDemo.java # 线程死锁:双锁交叉(lock)/环状(ring)/JUC(all) ├── thread/ThreadBlockDemo.java # 线程阻塞:blocked/wait/park/join/pool/io ├── thread/BusyWaitDemo.java # 空转 CPU 飙升 vs 正确 wait/notify(healthy 对照组) ├── gc/FullGcFrequentDemo.java # 频繁 Full GC:promote/humongous/system(误调System.gc)/leak ├── leak/StaticMemoryLeak.java # 静态集合泄漏:map/listener/weak(对照) └── leak/ThreadLocalLeak.java # ThreadLocal 泄漏:pool(内存)/static(数据串号) ``` ## 场景 → JVM 参数速查 | 场景 | 启动命令(JVM 参数已调好,可直接跑) | |---|---| | CPU 综合 | `java -cp target/classes com.demo.online.problem.cpu.CpuFullDemo mix` | | 堆溢出 | `java -Xms64m -Xmx64m -cp target/classes com.demo.online.problem.oom.HeapOomDemo heap` | | GC overhead | `java -Xms64m -Xmx64m -XX:+UseParallelGC -cp target/classes com.demo.online.problem.oom.HeapOomDemo gcoverhead` | | 栈溢出 | `java -Xss256k -cp target/classes com.demo.online.problem.oom.StackOomDemo sof` | | 元空间溢出 | `java -XX:MaxMetaspaceSize=32m -cp target/classes com.demo.online.problem.oom.MetaspaceOomDemo proxy` | | 直接内存溢出 | `java -XX:MaxDirectMemorySize=64m -Xmx128m -cp target/classes com.demo.online.problem.oom.DirectMemoryOomDemo direct` | | 线程死锁 | `java -cp target/classes com.demo.online.problem.thread.DeadLockDemo all` | | 线程阻塞 | `java -cp target/classes com.demo.online.problem.thread.ThreadBlockDemo all` | | 空转 CPU | `java -cp target/classes com.demo.online.problem.thread.BusyWaitDemo mix` | | 频繁 Full GC | `java -Xms256m -Xmx256m -Xmn32m -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1 -XX:+UseParallelGC -cp target/classes com.demo.online.problem.gc.FullGcFrequentDemo promote` | | 静态缓存泄漏 | `java -Xms256m -Xmx256m -cp target/classes com.demo.online.problem.leak.StaticMemoryLeak map` | | ThreadLocal 泄漏 | `java -Xms256m -Xmx256m -cp target/classes com.demo.online.problem.leak.ThreadLocalLeak pool` | 完整手册见 [`docs/排查手册.md`](docs/排查手册.md)(每个场景含预期现象 + 逐步排查命令 + 修复与验证)。 ## 排查工具箱速查 | 目的 | 命令 | |---|---| | 找最耗 CPU 的进程 | `top` | | 进程内最耗 CPU 的线程(TID) | `top -H -p ` | | TID 十进制→十六进制 | `printf '%x\n' ` | | 线程栈 / 死锁检测 | `jstack `(出现 `Found one Java-level deadlock` 即死锁) | | 堆概况 / 大对象 | `jmap -heap ` / `jmap -histo:live \| head` | | GC 统计(FGC/YGC/耗时) | `jstat -gcutil 1000` | | 导出堆转储 | `jmap -dump:format=b,file=/tmp/x.hprof ` | | 查看 JVM 参数 / 类加载 | `jcmd VM.flags` / `GC.class_histogram` | | 在线诊断(火焰图) | `arthas`:`thread -n 3`、`profiler start --event cpu` | ## 演练建议路径(从易到难) 1. **CPU 100%**:`CpuFullDemo loop` → `top -H` → `jstack` 三次定位热点行 2. **线程死锁**:`DeadLockDemo all` → `jstack` 直接看 JVM 自检出的死锁环 3. **线程阻塞**:`ThreadBlockDemo all` → 统计各状态线程 → 逐个讲应对策略 4. **堆溢出**:`HeapOomDemo heap` → `jmap -histo` 找占用大头 5. **频繁 Full GC**:`FullGcFrequentDemo promote` → `jstat -gcutil` 观察 FGC 曲线 → 对照讲解晋升与老年代参数 6. **内存泄漏**:`StaticMemoryLeak map` → 连续 `jmap -histo:live` 两次,看字节数不降反升 7. **元空间/直接内存**:进阶,讲「堆外不是 -Xmx 管」的经典误区 8. **ThreadLocal 串号**:安全面试题,`ThreadLocalLeak static` 演示脏数据 ## 免责提示 - 所有 Demo 只消耗**本进程内**的资源,不影响宿主机其它进程;但 CPU 场景会真的把核打满、OOM 场景会占满内存,请在演示/测试环境运行,别在生产机跑。 - `StackOomDemo thread`、`DirectMemoryOomDemo unsafe` 会吃系统内存/进程数上限,慎用并提前预估资源。