本周负责对一个 Web 应用进行故障分析,最终发现应用停止响应故障是由于在特定情况下 java class loader 所引发的严重内存泄露造成的,在此作以记录。
该 Web 应用故障表现为运行一段时间后,会出现服务停止响应的情况,间隔时间也很随机。在对其 javacore 分析后发现,停止响应的原因在于 jvm heap 耗尽,导致 web container 工作线程抛出了 out of memory 异常。
进一步对 heap dump 分析发现,应用 jvm 中发生了严重的内存泄露,而且泄露对象数量和占用的内存空间都很多,其根本的原因是由于 jvm class loader 泄露。下面的就是对比两次间隔一段负载后的 heap 变化情况(验证环境):
可以看到虽然 compound class loader 数量没有增加,但其引用的对象容量却大大增加了。我们知道在 java 中 class loader 用于加载 Class 定义并为其生成类的实例(Classs 实例),而且所有对象实例会引用其 Class 实例,这样就形成如下引用关系:
在 WebSphere、Tomcat 和 JBoss 等 jvm 运行环境中,class loader 是有层次的,每个层次的 class loader 作用和生命周期是不同的,以当前应用系统所部署的 WebSphere 为例,其结构如下:
其中的“WAS 扩展类装入器”为 com/ibm/ws/bootstrap/ExtClassLoader,“WAS 复合类装入器”为 com/ibm/ws/classloader/CompoundClassLoader 类型。
回到这里讨论的 Web 应用上,通过应用部署的人员了解到,当前系统在每次更新发布版本应用后,都会有选择的重新启动应用服务器(server),更多的时候为了不影响部署在同一应用服务器上的其它应用,在重新部署应用后不会同时重新启动应用服务器
,这样一来,由于 jvm 中 class loader 生命周期的不同,就会出现下面描述的情况,而结果就是出现大范围的内存泄露:
其根本原因就在于应用级生命周期的 class loader 及期所有加载的类和类的实例对象与服务器级生命周期的 class loader 加载的类的实例存在引用关系,造成重新发布应用而不重新启动应用服务器后,jvm 的泄露所以上一应用所加载、创建的对象实例。
可见这种内存泄露量是巨大的。
对于这种 jvm class loader 引发的内存泄露,这里有篇文章讨论的非常详细,同时也提出了一些可能的原因和解决方法,这里就不详细说明了,建议参考。
关于 Class 类加载器内存泄漏问题的探讨
类装入器查看器设置
说句题外话,这个端午节过得酒气很重,现在才冲回来,头晕,但洒店的网络现在也正常了很多。大家端午节同乐~~
// 2009.05.30 0:12 添加 ////
这几篇系列文章很好的介绍了 IBM JDK 垃圾收集及内存管理机制,把这些基础的重要技术细节说明的非常详细,在这里推荐下。另外,可以结合 IBM JVM Diagnostics Guide 来看,对 jvm 层面的性能优化和故障排除很对胃口。
IBM JDK 垃圾收集及内存管理机制 - (1)
IBM JDK 垃圾收集及内存管理机制 - (2)
IBM JDK 垃圾收集及内存管理机制 - (3)
// 2009.06.06 14:09 添加 ////
作者:lzy.je
出处:http://lzy.iteye.com
本文版权归作者所有,只允许以摘要和完整全文两种形式转载,不允许对文字进行裁剪。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
- 大小: 14 KB
- 大小: 21.9 KB
- 大小: 27 KB
- 大小: 61.6 KB
- 大小: 199.4 KB
- 大小: 20.4 KB
- 大小: 62.9 KB
分享到:
相关推荐
内存泄漏是指程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄漏可能看似无害,但随着时间推移,未释放的内存积累,可能导致程序运行缓慢或耗尽系统资源。Java中,内存泄漏通常是因为引用了不再使用的...
1. **Class Loader**:类加载器负责将.class文件加载到JVM内存中。它遵循双亲委派模型,确保类只被加载一次,防止类的重复加载和安全问题。 2. **Execution Engine**:执行引擎,有时称为解释器,负责解释和执行...
Android 内存泄露是一个常见的问题,它会导致应用程序的性能下降,甚至崩溃。Memory Analyzer Tool(MAT)是一个功能强大且广泛使用的内存泄露分析工具。本文将详细介绍如何使用 MAT 分析 Android 应用程序中的内存...
本篇文章将通过一个简单的"JVM模拟内存泄漏代码"来深入探讨堆内存泄漏和元空间泄漏,帮助开发者理解和预防这类问题。 堆内存泄漏是指程序中的对象在不再被使用后,由于某些原因没有被垃圾收集器回收,导致堆内存...
system class loader 在没有指定装载器的情况下默认装载用户类,在 Sun Java 1.5 中既 sun.misc.Launcher$AppClassLoader。 现在,让我们准备 heap dump 文件。我们创建了一个名为 Pilot 的类,它有两个成员变量:...
在 Java 中,类加载器(Class Loader)是负责加载类的组件。类加载器可以将类文件加载到内存中,以便 JVM 可以使用这些类。 在 Java 中,类加载器可以分为三种:BootstrapClassLoader、ExtensionClassLoader 和 ...
JVM的主要组件包括:类加载器(Class Loader)、执行引擎(Execution Engine)、本地接口(Native Interface)以及运行时数据区(Runtime Data Area),这些组件共同协作,确保Java程序的正常执行。 2. 类加载器 类...
- **内存管理**:JVM自动管理程序的内存,包括垃圾回收机制,可以有效避免内存泄漏等问题。 - **安全性**:JVM提供了强大的安全模型,能够防止恶意代码的入侵,保护系统的安全。 #### 2. 类装载器的体系结构 类...
了解JVM的内存机制对于优化Java应用程序、排查内存泄漏和理解程序运行行为至关重要。深入学习这些概念可以帮助我们编写更高效、更稳定的Java代码,并有效应对各种运行时错误。在实际开发中,结合内存分析工具,如...
- **类装载器(Class Loader)**:运行时,JVM使用类装载器加载所需的类,每个类都有自己的命名空间,以防止类之间的冲突。本地类共享同一地址空间,而外部类则有自己的独立空间。 - **字节码校验**:加载后的字节...
JVM的架构设计为Java程序提供了一个“一次编写,到处运行”的平台。它主要包括以下几个关键组件: 1. 类加载器(Class Loader):负责加载编译后的Java类文件到JVM中。 2. 执行引擎(Execution Engine):负责执行...
这种错误的出现通常是由于Jvm的内存不足或内存泄露导致的。 出现java.lang.OutOfMemoryError的原因有多种,常见的有以下几种: 1. 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。 2. 集合类中有对对象...
Java程序的内存分配主要涉及到Java虚拟机(JVM)的工作原理和内存结构。JVM是一个抽象的计算模型,它使得Java代码能够在任何支持JVM的平台上运行,无需针对特定硬件进行重新编译。以下是关于Java程序内存分配的详细...
Java虚拟机(JVM)是Java编程语言的核心组成部分,它为Java程序提供了运行环境,使得代码能在任何支持Java的平台上无缝执行,实现了“一次编写,到处运行”的目标。本资源《深入了解Java虚拟机》深入剖析了JVM的工作...
JVM还提供了垃圾回收机制,自动管理对象的生命周期,避免了手动内存管理可能引发的内存泄漏和悬挂指针等问题。 #### 线程管理 在分布式应用中,线程管理尤为重要。JVM支持多线程执行,能够高效地处理并发任务。每...
垃圾回收是Java的另一个核心机制,其主要功能是在程序运行过程中自动回收不再使用的对象所占用的内存空间,从而避免内存泄漏问题。Java的垃圾回收机制主要包括以下几个方面: - **标记-清除算法**:最基础的垃圾回收...
Java虚拟机(JVM,Java Virtual Machine)是Java语言的核心组成部分,它扮演着至关重要的角色,使得Java程序具有“一次编写,到处运行”的跨平台特性。JVM是一种抽象的计算机模型,它允许开发者编写Java代码,并在...
1. **编译阶段**:Java源代码(.java)文件首先通过Java编译器(javac)被编译成字节码文件(.class),这些字节码是一种中间代码,并非直接可执行的机器码。字节码的设计确保了其与平台无关性,因为它们不包含任何特定...
Java语言以其简洁和高效著称,主要依赖于两大部分:JVM(Java虚拟机)的内存管理和Class Loader机制。理解这两点,能帮助我们解决大部分与对象和配置相关的问题。 1. JVM的内存管理: JVM内存管理主要包括堆内存、...
#### 一、内存泄漏与内存溢出 - **内存泄漏**:指程序在申请内存后,无法释放已分配的内存空间,导致随着时间的推移,程序所消耗的内存逐渐增加。这通常是因为程序员未能正确地管理内存资源,如忘记释放不再使用的...