从 JDK 基础异常到 JVM 内存调优,覆盖空指针、集合遍历、线程安全、BigDecimal 精度等高频问题,每条都经过社区验证。
编译错误、字节码、注解处理、VerifyError
类加载、NoSuchMethod、jar 冲突、Native 库加载
编译能过、运行却抛 NoSuchMethodError,九成是编译期与运行期的依赖版本不一致。
System.loadLibrary 报 UnsatisfiedLinkError,多是库不在 java.library.path、库名或架构不匹配。
ClassNotFoundException 多因 classpath 缺依赖;NoClassDefFoundError 常因静态初始化失败。
Metaspace 存类元数据且走本地内存,报错多是动态生成类过多或 ClassLoader 泄漏、旧类卸载不掉。
OOM、GC 调优、内存泄漏、栈溢出
堆还没满就 OOM,因为直接内存不在堆里、GC 管不到,多是 Netty 等 NIO 缓冲没释放或没设上限。
不是堆真不够,而是 GC 花了超 98% 的时间却只回收不到 2%,根子还是堆小或存在泄漏。
Metaspace 存类元数据且走本地内存,报错多是动态生成类过多或 ClassLoader 泄漏、旧类卸载不掉。
堆被对象占满、GC 回收不回空间时抛出,用 -XX:+HeapDumpOnOutOfMemoryError 留快照,调大 -Xmx 只是治标。
不是堆内存不够,是递归或调用链太深把线程栈顶穿;先查递归出口,-Xss 调大只是应急。
ThreadLocal 在线程池里用完不 remove 会累积无主 value,最终把堆吃满抛出 OutOfMemoryError。
死锁、线程安全、并发集合、线程池
SimpleDateFormat 内部共享 Calendar,定义成静态变量后并发会报 NumberFormatException 或日期串台。
它不只在多线程出现,单线程遍历时直接增删元素一样触发;改用 removeIf 或 Iterator.remove 即可。
死锁不是异常,是线程各握对方要的锁互相永久等待;用 jstack 能直接打出环上线程。
ThreadLocal 在线程池里用完不 remove 会累积无主 value,最终把堆吃满抛出 OutOfMemoryError。
不是堆满,是操作系统拒绝再创建线程:ulimit -u 或 kernel.threads-max 到顶,或线程栈吃光 native 内存。
NPE、InvocationTarget、反射
文件/Socket、NIO、编码、序列化
集合遍历、BigDecimal、日期时间、Stream
JNI、java.library.path、JVM 参数、ulimit
报 IOException: Too many open files 是 Linux 文件描述符上限被击穿,多半是 FD 泄漏或 ulimit 没生效。
System.loadLibrary 报 UnsatisfiedLinkError,多是库不在 java.library.path、库名或架构不匹配。
不是堆满,是操作系统拒绝再创建线程:ulimit -u 或 kernel.threads-max 到顶,或线程栈吃光 native 内存。