核心概念:JVM 内存模型
要理解 WebLogic 的内存,必须先理解它所运行的 Java 虚拟机 的内存结构,JVM 内存主要分为两大块:堆内存 和 非堆内存。

堆内存
这是 JVM 管理的最大、最核心的一块内存,用于存放对象实例和数组,几乎所有通过 new 关键字创建的对象都存储在堆中。
堆内存是多线程共享的,也是垃圾回收 的主要区域。
-
新生代
- 目的:新创建的对象首先在这里分配内存,大部分对象的生命周期都很短。
- 结构:
- Eden 区:新对象的诞生地。
- Survivor 区 (S0, S1):经过一次 Minor GC 后仍存活的对象会被移动到 Survivor 区,两个 Survivor 区会互相“倒腾”,每次只使用其中一个。
- 回收过程:Minor GC (或 Young GC) 会频繁地清理新生代,大部分对象在 Eden 区就会被回收,只有少量“幸存者”会进入老年代。
-
老年代
- 目的:存放生命周期较长的对象,例如在多次 Minor GC 后依然存活的对象。
- 回收过程:当老年代空间不足时,会触发 Major GC (或 Full GC),Full GC 会回收整个堆(包括新生代和老年代),通常耗时较长,可能导致应用停止响应(Stop-The-World),是性能调优的重点关注对象。
非堆内存
这部分内存不用于存放对象实例,而是用于存储 JVM 自身运行所需的数据、类信息、线程、JIT 编译后的代码等。
-
方法区
- :类信息(类的结构)、常量、静态变量、即时编译器编译后的代码缓存等。
- HotSpot 的实现:在 JDK 1.8 及之后,方法区被元空间 取代,元空间使用的是本地内存,而不是 JVM 堆内存,这解决了之前方法区内存不足的问题(
OutOfMemoryError: PermGen space)。
-
虚拟机栈
- 作用:为每个线程创建私有的内存区域,存储方法调用(栈帧)、局部变量、操作数栈、动态链接等。
- 异常:如果线程请求的栈深度大于虚拟机所允许的深度,会抛出
StackOverflowError,JVM 栈内存可以动态扩展,但扩展时无法申请到足够内存,会抛出OutOfMemoryError。
-
本地方法栈
- 与虚拟机栈类似,但为虚拟机使用到的 Native 方法 服务。
-
程序计数器
一块较小的内存空间,可以看作是当前线程所执行的字节码行号指示器。
-
直接内存
- 作用:不受 JVM 堆大小限制的内存区域,通常用于 NIO (New I/O),通过
ByteBuffer.allocateDirect()分配。 - 影响:直接内存也会占用物理内存,如果申请过多,可能导致物理内存不足,从而触发 OOM。
- 作用:不受 JVM 堆大小限制的内存区域,通常用于 NIO (New I/O),通过
WebLogic 内存配置
WebLogic 内存配置主要通过两个核心文件来完成:setDomainEnv.sh (Linux/Unix) 或 setDomainEnv.cmd (Windows)。
关键 JVM 参数
在 setDomainEnv 脚本中,你会看到以下关键的内存相关参数:
-
堆内存大小
-Xms:JVM 堆的初始大小,建议设置为与-Xmx相同的值,以避免堆动态扩展带来的性能开销。-Xmx:JVM 堆的最大大小,这是最重要的参数,它限制了 WebLogic 服务器能使用的最大堆内存。
-
非堆内存大小
-XX:MaxPermSize(JDK 1.7及之前):设置方法区 的最大大小,在 WebLogic 10.3.6 及之前的版本中很常见。-XX:MetaspaceSize(JDK 1.8及之后):设置元空间的初始大小,当元空间使用量超过这个值时,会触发 Full GC 进行回收。-XX:MaxMetaspaceSize(JDK 1.8及之后):设置元空间的最大大小。强烈建议设置此参数,以防止元空间无限制地占用本地内存,导致系统崩溃。
-
垃圾回收器 选择
-Xms512m -Xmx1024m:表示初始堆内存为 512MB,最大堆内存为 1GB。-XX:+UseParallelGC:选择并行回收器,这是 WebLogic 默认的 GC 算法,适用于多核 CPU、对吞吐量要求高的应用,它会利用多个 CPU 进行垃圾回收,但 STW 时间可能较长。-XX:+UseG1GC:选择 G1 (Garbage-First) 回收器,JDK 9 之后成为默认回收器,它将堆划分为多个 Region,能更好地预测和控制 STW 时间,适用于大内存堆(> 4GB)的应用,是现代 WebLogic 部署的推荐选择。
示例配置
JDK 1.7 环境 (旧版):
# In setDomainEnv.sh
JAVA_OPTIONS="${JAVA_OPTIONS} -Xms1024m -Xmx2048m"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MaxPermSize=512m"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseParallelGC"
JDK 1.8+ 环境 (现代版):
# In setDomainEnv.sh
JAVA_OPTIONS="${JAVA_OPTIONS} -Xms2048m -Xmx4096m"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MetaspaceSize=256m"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MaxMetaspaceSize=512m"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseG1GC"
常见的内存问题与排查
当应用出现性能下降或崩溃时,内存问题是最常见的原因之一。
OutOfMemoryError: Java heap space
- 原因:堆内存空间不足,无法为新对象分配内存。
- 排查方法:
- 增加堆内存:临时增加
-Xmx值,看问题是否缓解。 - 分析内存泄漏:使用工具(如 Eclipse MAT, JProfiler, JVisualVM)分析 Full GC 后的堆转储文件,这些文件通常在 OOM 时自动生成(需要配置
-XX:+HeapDumpOnOutOfMemoryError),通过分析,可以找到哪些对象占用了大量内存,并定位到创建这些对象的代码。
- 增加堆内存:临时增加
OutOfMemoryError: PermGen space (JDK < 1.8)
- 原因:方法区(永久代)空间不足,通常是因为加载了大量的类、第三方库或应用频繁地动态生成类(如使用反射、CGLIB 等)。
- 解决方法:
- 增加
-XX:MaxPermSize值。 - 根本解决:升级到 JDK 1.8+,使用元空间,这个问题将得到极大改善。
- 增加
OutOfMemoryError: Metaspace (JDK >= 1.8)
- 原因:元空间耗尽,原因与
PermGen space类似,但更可能是因为没有设置-XX:MaxMetaspaceSize,导致元空间无限占用本地内存。 - 解决方法:
- 设置
-XX:MaxMetaspaceSize为一个合理的值。 - 检查是否有应用代码或框架(如 Spring、Hibernate)动态生成了过多未卸载的类。
- 设置
OutOfMemoryError: unable to create new native thread
- 原因:这不是 JVM 堆内存问题,而是操作系统级别的问题,每个线程都需要一定的本地内存来分配栈空间,JVM 已经分配了大量的堆内存,那么留给线程的本地内存就少了,当创建新线程时,如果请求的栈内存(
-Xss参数指定)加上已使用的堆内存超过了总物理内存,就会报错。 - 排查方法:
- 减小
-Xmx堆大小。 - 减小线程栈大小
-Xss。 - 检查应用是否有不必要的线程创建,优化线程池配置。
- 减小
最佳实践与调优建议
- 为 WebLogic 分配足够但不过量的内存:通常建议将
-Xmx设置为服务器物理内存的 40%-70%,并为操作系统和其他应用留出足够空间。 - 使用现代垃圾回收器:对于 WebLogic 12c 及以上版本,强烈推荐使用 G1GC,它提供了更好的可预测性。
- 监控是关键:持续监控是内存管理的基础。
- WebLogic Server Console:提供基本的 JVM 内存图表。
- Oracle Enterprise Manager (OEM):提供更全面、专业的监控和诊断功能。
- JDK 自带工具:
jstat,jmap,jstack等是命令行下的强大诊断工具。 - Prometheus + Grafana:现代化的开源监控方案,可以灵活地收集和展示 JVM 指标。
- 设置合理的元空间限制:在 JDK 1.8+ 环境下,务必设置
-XX:MaxMetaspaceSize,并观察其使用情况,预留 20% 的余量。 - 定期分析 GC 日志:开启 GC 日志 (
-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps),通过工具(如 GCViewer)分析 GC 频率、暂停时间,评估 GC 策略是否有效。 - 优化应用代码:最好的内存优化是优化应用本身,避免内存泄漏(如未关闭的连接、流、集合等),使用对象池,缓存策略要合理。
WebLogic 的 Java 内存管理本质上就是 JVM 内存管理在应用服务器上的实践,理解堆(新生代/老年代)和非堆(元空间/栈等)的划分,合理配置 -Xmx, -Xms, -XX:MaxMetaspaceSize 等关键参数,并选择合适的垃圾回收器,是保障 WebLogic 应用稳定运行的基础,遇到问题时,结合监控工具和内存分析工具进行深入排查,是解决内存难题的关键路径。
