标准答案

  1. 递归没有终止、调用链过深或栈帧过大可能造成 StackOverflowError。
  2. Java heap space 表示堆无法为对象分配空间,原因可能是存活对象过多或堆上限过小。
  3. OutOfMemoryError 还可能涉及元空间、直接内存、线程创建和其他本地资源。
  4. 修复应根据错误类型、堆转储、线程转储和本地内存指标定位,不应统一扩大所有内存。

题目解析

StackOverflowError 通常要看调用深度和线程栈,Java heap space 要看堆中存活对象和分配上限,其他 OutOfMemoryError 还可能来自元空间、直接内存、线程或 native 资源。分类是排查起点。

无界缓存、队列、监听器和 ThreadLocal 都可能让堆对象长期存活;递归和线程过多则可能消耗栈或线程资源。扩大错误区域的上限可能只是延后故障,甚至挤压其他区域。

生产取证要有受控的堆/线程转储、GC 日志、类加载和本地内存指标,并注意文件大小和敏感信息。没有时间线,单条错误字符串很难证明根因。

常见误区

  • 误区:看到 OOM 就只改 Xmx。改正:先确认是堆、栈、元空间、直接内存、线程还是 native 资源。
  • 误区:把递归栈溢出改成堆大小问题。改正:检查递归终止条件、调用深度和线程栈配置。
  • 误区:生产环境只保留错误字符串。改正:配置受控转储、GC/线程指标和取证权限,保留故障时间线。

作者信息