jvm探查内存不足/内存泄漏问题

探查内存不足/内存泄漏问题
 
问题描述

内存不足 (OOM) - 由于 java 堆或本地内存中的内存耗尽,应用程序显示“内存不足”错误。

内存泄漏 - java 堆或本地内存的持续内存增长,最终将导致内存不足状态。调试内存泄漏状态的技术与调试内存不足状态的技术相同。

故障排除
请注意,并非下面所有任务都需要完成。有些问题仅通过执行几项任务就可以解决。

快速链接:

Java 堆、本地内存和进程大小
进程地址空间和物理内存之间的差异
为什么会发生 OOM 问题,JVM 在这种情况下如何处理?
排除故障的步骤
确定是 Java OOM 还是本地 OOM
Java OOM
本地 OOM
Jrockit 特定特性
参考文献
Java 堆、本地内存和进程大小

Java 堆 - 这是 JVM 用来分配 java 对象的内存。java 堆内存的最大值用 java 命令行中的 .Xmx 标志来指定。如果未指定最大的堆大小,那么该极限值由 JVM 根据诸如计算机中的物理内存量和该时刻的可用空闲内存量这类因素来决定。始终建议您指定最大的 java 堆值。

本地内存 - 这是 JVM 用于其内部操作的内存。JVM 将使用的本地内存堆数量取决于生成的代码量、创建的线程、GC 期间用于保存 java 对象信息的内存,以及在代码生成、优化等过程中使用的临时空间。

如果有一个第三方本地模块,那么它也可能使用本地内存。例如,本地 JDBC 驱动程序将分配本地内存。

最大本地内存量受到任何特定操作系统上的虚拟进程大小限制的约束,也受到用 .Xmx 标志指定用于 java 堆的内存量的限制。例如,如果应用程序能分配总计为 3 GB 的内存量,并且最大 java 堆的大小为 1 GB,那么本地内存量的最大值可能在 2 GB 左右。 进程大小 - 进程大小将是 java 堆、本地内存与加载的可执行文件和库所占用内存的总和。在 32 位操作系统上,进程的虚拟地址空间最大可达到 4 GB。从这 4 GB 内存中,操作系统内核为自己保留一部分内存(通常为 1 - 2 GB)。剩余内存可用于应用程序。

Windows缺省情况下,2 GB 可用于应用程序,剩余 2 GB 保留供内核使用。但是,在 Windows 的一些变化版本中,有一个 /3GB 开关可用于改变该分配比率,使应用程序能够获得 3 GB。有关 /3GB 开关的详细信息,可以在以下网址中找到:
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/ddtools/hh/ddtools/bootini_1fcj.asp

RH Linux AS 2.1 - 3 GB 可用于应用程序。

对于其它操作系统,请参考操作系统文档了解有关配置。

返回页首

进程地址空间和物理内存之间的差异

每个进程都获得其自有的地址空间。在 32 位操作系统中,此地址空间范围为 0 到 4 GB。此范围与计算机的可用随机存取内存 (RAM) 或交换空间无关。计算机中的可用物理内存总量是该计算机上的可用 RAM 和交换空间之和。所有运行的进程共享这些物理内存。

进程内的存储地址是虚拟地址。内核将此虚拟地址映射到物理地址上。物理地址指向物理内存中的某个位置。在任一给定时间,计算机中运行进程所使用的全部虚拟内存的总和不能超过该计算机上可用物理内存的总量。

返回页首

为什么会发生 OOM 问题,JVM 在这种情况下如何处理?

java 堆中的内存不足
如果 JVM 不能在 java 堆中获得更多内存来分配更多 java 对象,将会抛出 java 内存不足 (java OOM) 错误。如果 java 堆充满了活动对象,并且 JVM 无法再扩展 java 堆,那么它将不能分配更多 java 对象。

在这种情况下,JVM 让应用程序决定在抛出 java.lang.OutOfMemoryError 后该执行什么操作。例如,应用程序可以处理此错误,并决定以安全方式自行关闭或决定忽略此错误。如果应用程序不处理此错误,那么抛出此错误的线程将退出(如果您进行 java Thread Dump,那么将看不到该线程)。

在使用 Weblogic Server 的情况下,如果此错误是由某个执行线程抛出的,则会处理此错误并将其记录在日志中。如果连续抛出此错误,那么核心运行状况监视器线程将关闭 Weblogic Server。

本地堆中的内存不足
如果 JVM 无法获得更多本地内存,它将抛出本地内存不足(本地 OOM)错误。当进程到达操作系统的进程大小限值,或者当计算机用完 RAM 和交换空间时,通常会发生这种情况。

当发生这种情况时,JVM 处理本地 OOM 状态,记录说明它已用完本地内存或无法获得内存的消息,然后退出。如果 JVM 或加载的任何其它模块(如 libc 或第三方模块)不处理这个本地 OOM 状态,那么操作系统将给 JVM 发送命令 JVM 退出的 sigabort 信号。通常情况下,JVM 收到 sigabort 信号时将会生成一个核心文件。

返回页首

排除故障的步骤

确定是 Java OOM 还是本地 OOM:
如果 stdout/stderr 消息说明这是一个 java.lang.OutOfMemoryError,那么这就是 Java OOM
如果 stdout/stderr 消息说明无法获得内存,那么这就是本地 OOM
请注意,上述消息仅发送到 stdout 或 stderr 中,而不发送到应用程序特定的日志文件(如 weblogic.log)

返回页首

对于 Java OOM:

收集和分析 verbose gc 输出
在 java 命令行中添加“-verbosegc”标志。这样将会把 GC 活动信息打印到 stdout/stderr。将 stdout/stderr 重定向到一个文件。运行应用程序,直到该问题重现。
确保 JVM 在抛出 java OOM 之前完成下列任务完整 GC 运行:
执行一次完整 GC 运行,并且删除了所有不可及对象以及虚可及、弱可及、软可及对象,并回收了那些空间。有关不同级别的对象可及性的详细信息,可以在以下网址中可找到:
http://java.sun.com/developer/technicalArticles/ALT/RefObj

您可以检查是否在发出 OOM 消息之前执行了完整 GC 运行。当完成一次完整 GC 运行时,将会打印类似如下消息(格式取决于 JVM - 请查看 JVM 帮助信息以了解有关格式)

[memory ] 7.160: GC 131072K->130052K (131072K) in 1057.359 ms

你可能感兴趣的:(WebSphere)