Ubuntu上WebLogic内存溢出的定位与解决
一、快速判断 OOM 类型
- 查看异常关键字与输出位置:
- Java 堆溢出:日志出现 java.lang.OutOfMemoryError: Java heap space,通常伴随 stdout/stderr 的 GC 日志;这类错误不一定写入 weblogic.log。
- 元空间溢出(Java 8 之前):出现 java.lang.OutOfMemoryError: PermGen space。
- 本机内存溢出(堆外):出现 java.lang.OutOfMemoryError: unable to create new native thread 或 native memory exhausted,JVM 可能记录“native OOM”并退出,甚至被 SIGABRT 终止。
- 初步结论:先区分是 Java 堆、元空间 还是 本机内存,再决定是调参、改代码还是查系统限制。
二、Java 堆溢出 Java heap space 的处理
- 打开并保留 GC 日志,便于判断是“容量不足”还是“泄漏”:
- 建议参数:
- HotSpot:
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:<path>/gc.log
- JRockit:
-verbose:gc gcpause memdbg
- 观察 GC 后回收效果与停顿,确认是否“回收后仍接近满堆”。
- 调整堆大小(示例):
- 编辑域目录下的 bin/setDomainEnv.sh,在 JAVA_OPTIONS 或相应位置设置:
-Xms4g -Xmx4g(将堆锁定为合适上限,避免运行期频繁扩缩)
- 注意:堆上限受 物理内存/交换空间 与 进程地址空间 限制,32 位进程上限约 4GB;64 位虽不受 4GB 限制,但仍受系统资源约束。
- 定位泄漏与优化对象生命周期:
- 发生 OOM 时导出 Heap Dump(如
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path>),用 Eclipse MAT 或 VisualVM 分析占用最高的对象与 GC Roots 路径。
- 常见根因:缓存未设上限、集合无限增长、资源未关闭(JDBC Statement/ResultSet、JNDI、JMS 等)。
- 案例提示:使用 Hibernate 的 StatefulPersistenceContext 长事务持有大量实体,易在会话周期内撑爆堆,需优化会话生命周期与批量处理策略。
三、元空间 Metaspace 溢出 PermGen 的处理(Java 7 及更早)
- 现象与原因:部署/热加载时大量类加载,超过 PermGen 上限。
- 解决:在 setDomainEnv.sh 提升元空间上限(Java 7):
-XX:MaxPermSize=512m(或更高,视应用而定)
- 注意:Java 8+ 使用 Metaspace 替代 PermGen,需改用
-XX:MaxMetaspaceSize 控制上限。
四、本机内存溢出 native OOM 的处理
- 典型触发:线程数过多、JNI/第三方本地库、Direct ByteBuffer、大量类加载、进程地址空间/容器限制。
- 排查与缓解:
- 监控进程虚拟内存增长(如
pmap -x <pid> | tail、smem、/proc/<pid>/status 的 VmSize/VmRSS),确认是否逼近系统/容器上限。
- 降低线程数、复用线程(合理设置 WebLogic 线程池与工作管理器)、避免创建过多阻塞线程。
- 减少 Direct Memory 占用,审视 NIO/缓存使用;尽量使用纯 Java 驱动替代本地驱动。
- 检查 ulimit -v/-u、容器(如 Docker/K8s)内存限制;必要时提升系统 swap 或启用 zram/zswap 缓解瞬时压力(仅缓解,不替代根因修复)。
- 若由第三方本地模块引起,协同供应商排查本机内存分配与泄漏。
五、Ubuntu 系统层面的优化与监控
- 资源与稳定性:
- 使用 top/htop 观察 RES/VIRT,用 vmstat/iostat/sar 持续监测系统负载与 I/O;必要时用 cgroups 限制 WebLogic 资源,避免影响同机服务。
- 调整 OOM Killer 倾向:
echo -1000 > /proc/<pid>/oom_score_adj,降低关键进程被系统杀死的概率(治标不治本,优先解决泄漏/配置问题)。
- WebLogic 侧配置:
- 结合负载合理设置 线程池、数据库连接池 等关键参数;利用 Administration Console 与性能监控工具做容量评估与瓶颈定位。
- 监控体系:
- 引入 Prometheus + Grafana 采集 JVM GC/内存、线程、类加载、系统资源 等指标,设置阈值告警,支撑容量规划与滚动优化。