- 浏览: 427129 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
Glogo:
楼主您好,我在试验您的代码的时候发现新开的三个子线程并没有一直 ...
java 高并发 ReentrantLock -- 可重入的锁 -
univasity:
最近发觉也被限速了,投诉一下就好一会~~ 看来明天又要和电信M ...
ADSL上网速度慢 都是帐号限速惹的祸 -
liuyuanhui0301:
java 高并发 ReentrantLock -- 可重入的锁 -
dang_java:
呵.很好的说明文档.
JXTA技术与应用发展 -
helloqidi:
谢谢,学习了
SQL中exists和in的区别
转载:http://blog.dynatrace.com/2011/04/20/the-top-java-memory-problems-part-1/
Memory and Garbage Collection problems are still the most prominent issues in any java application. One of the reasons is that the very nature of Garbage Collection is often misunderstood. This prompted me to write a summary of some of the most frequent and also most obscure memory related issues that I have encountered in my time. I will cover the causes of memory leaks, high memory usage, class loader problems and GC configuration and how to detect them. We will begin this series with the best known one - memory leaks.
Memory Leaks
A memory leak is the most-discussed java memory issue there is. Most of the time people only talk about growing memory leaks, that is the continuous rise of leaked objects. They are in comparison, the easiest to track down as you can look at trending or histogram dumps.
In the picture we see the dynaTrace trending dump facility. You can achieve similar results manual by using jmap -histo <pid> multiple times and compare the results. Single object leaks are less thought about. As long as we have enough memory they seldom pose a serious problem. From time to time though there are single object leaks that occupy a considerable amount of memory and become a problem. The good news is that single big leaks are easily discovered by todays heap analyzer tools, as they concentrate on that.
Lastly there is also the particularly nasty, but in reality rarely, seen version of a lot of small, unrelated memory leaks. It's theoretically possible, but in reality it would need a lot of seriously bad programmers working on the same project. So let's look at the most common causes for memory leaks.
Thread Local Variables
ThreadLocals are used to bind a variable or a state to a thread. Each thread has its own instance of the variable. They are very useful but also very dangerous. They are often used to track a state, like the current transaction id, but sometimes they hold a little more information. A thread local variable is referenced by its thread and as such its lifecycle is bound to it. In most application servers threads are reused via thread pools and thus are never garbage collected. If the application code is not carefully clearing the thread local variable you get a nasty memory leak.
These kind of memory leaks can easily be discovered with a heap dump. Just take a look at the ThreadLocalMap in the heap dump and follow the references.
You can then also look at the name of the thread to figure out which part of your application is responsible for the leak.
Mutable static fields and collections
The most common reason for a memory leak is the wrong usage of statics. A static variable is held by its class and subsequently by its classloader. While a class can be garbage collected it will seldom happen during an applications lifetime. Very often statics are used to hold cache information or share state across threads. If this is not done diligently it is very easy to get a memory leak. Especially static mutable collections should be avoided at all costs for just that reason. A good architectural rule is not to use mutable static objects at all, most of the time there is a better alternative.
Circular and complex bi-directional references
This is my favorite memory leak. It is best explained by example:
org.w3c.dom.Document doc = readXmlDocument();
org.w3c.dom.Node child = doc.getDocumentElement().getFirstChild();
doc.removeNode(child);
doc = null;
At the end of the code snippet we would think that the DOM Document will be garbage collected. That is however not the case. A DOM Node object always belongs to a Document. Even when removed from the Document the Node Object still has a reference to its owning document. As long as we keep the child object the document and all other nodes it contains will not be garbage collected. I've see this and other similar issues quite often.
JNI memory leaks
This is a particularly nasty form or memory leak. It is not easily found, unless you have the right tool and it is also not known to a lot of people. JNI is used to call native code from java. This native code can handle, call and also create java objects. Every java object created in a native method begins its life as a so called local reference. That means that the object is referenced until the native method returns. We could say the native method references the java object. So you don't have a problem unless the native method runs forever. In some cases you want to keep the created object even after the native call has ended. To achieve this you can either ensure that it is referenced by some other java object or you can change the local reference into a global reference. A global reference is a GC root and will never be garbage collected until explicitly deleted by the native code. The only way to discover such a memory leak is to use a heap dump tool that explicitly shows global native references. If you have to use JNI you should rather make sure that you reference these objects normally and forgo global references altogether.
You can find this sort of leak when your heap dump analysis tool explicitly marks the GC Root as a native reference, otherwise you will have a hard time.
Wrong implementation of equals/hashcode
It might not be obvious on the first glance, but if your equals/hashcode methods violate the equals contract it will lead to memory leaks when used as a key in a map. A HashMap uses the hashcode to lookup an object and verify that it found it by using the equals method. If two objects are equal they must have the same hashcode, but not the other way around. If you do not explicitly implement hashcode yourself this is not the case. The default hashcode is based on object identity. Thus using an object without a valid hashcode implementation as a key in a map, you will be able to add things but you will not find them anymore. Even worse if you re-add it, it will not overwrite the old item but really add a new one. And just like that you have memory leak. You will find it easily enough as it is growing, but the root cause will be hard to determine unless you remember this one.
The easiest way to avoid this is to use unit testcases and one of the available frameworks that tests the equals contract of your classes (e.g. http://code.google.com/p/equalsverifier/).
Classloader Leaks
When thinking about memory leaks we think mostly about normal java objects. Especially in application servers and OSGi containers there is another form of memory leak, the class loader leak. Classes are referenced by their classloader and normally they will not get garbage collected until the classloader itself is collected. That however only happens when the application gets unloaded by the application server or OSGi container. There are two forms of Classloader Leaks that I can describe off the top of my head.
In the first an object whose class belongs to the class loader is still referenced by a cache, a thread local or some other means. In that case the whole class loader, meaning the whole application cannot be garbage collected. This is something that happens quite a lot in OSGi containers nowadays and used to happen in JEE Application Servers frequently as well. As it is only happens when the application gets unloaded or redeployed it does not happen very often.
The second form is nastier and was introduced by bytecode manipulation frameworks like BCEL and ASM. These frameworks allow the dynamic creation of new classes. If you follow that thought you will realize that now classes, just like objects, can be forgotten by the developer. The responsible code might create new classes for the same purpose multiple times. As the class is referenced in the current class loader you get a memory leak that will lead to an out of memory in the permanent generation. The real bad news is that most heap analyzer tools do not point out this problem either, we have to analyze it manually, the hard way. This form or memory leak became famous due to an issue in an older version of hibernate and its usage of CGLIB.
Summary
As we see there are many different causes for memory leaks and not all of them are easy to detect. In my next post I will look at further java memory problems, so stay tuned.
发表评论
-
JVM 深入笔记
2012-04-12 20:36 1000JVM 深入笔记(1)内存区域是如何划分的? 一个超短的前言 ... -
JVM启动参数
2011-06-10 16:27 964java [jvmargs] class [arguments ... -
JVM指令集 和 一个异常例子
2011-05-19 16:14 1018指令码 助记符 说明 0x00 nop ... -
BTrace使用简介
2011-04-19 13:51 777该文转载自:http://rdc.taobao.com/tea ... -
大方法的执行性能与调优过程小记
2011-04-18 16:20 804该文章转载自:http://rdc.taobao.com/te ... -
十个最好的Java性能故障排除工具
2011-04-18 16:02 924推荐十个最好的Java性能 ... -
两个OOM Cases排查过程的分享
2011-04-18 15:39 929分享一下两个OOM Cases的查找过程,一个应用是Nativ ... -
Monitoring Java garbage collection with jstat
2011-04-18 15:28 858The original article is at : ht ... -
理解Heap Profling名词-Shallow和Retained Sizes
2011-04-18 14:58 974所有包含Heap Profling功能的工具(MAT, You ... -
Java深度历险(四)——Java垃圾回收机制与引用类型
2011-04-01 08:18 980Java语言的一个重要特性 ... -
Thread Dump 和Java应用诊断
2011-03-30 08:08 1130Thread Dump 和Java应用诊断 ... -
Memory Analysis Part 1 – Obtaining a Java Heapdump
2011-03-14 16:06 1119For troubleshooting Java memory ... -
Java Memory Leaks et al. (2. Act)
2011-03-14 15:37 924The first act of this blog-seri ... -
Erlang memory architecture vs Java memory architecture
2011-03-14 15:36 909I read a really, really interes ... -
The Java Memory Architecture (1. Act)
2011-03-14 15:15 1411One of the biggest strength of ... -
Permanent generation
2011-03-14 14:53 1270版权声明:转载时请以 ... -
JVM内存模型以及垃圾回收
2011-03-13 09:38 983内存由 Perm 和 Heap 组成. 其中 Heap ... -
Java虚拟机垃圾回收机制
2011-03-13 09:31 825一、相关概念 基本 ... -
JVM结构
2011-03-10 14:43 889类文件格式 JVM使用一 ... -
OOM与JVM(转)
2009-03-24 15:49 966OOM与JVM(转) 2008年08月08日 星期五 15: ...
相关推荐
j-jtp02244-Java.theory.and.practice-Fixing.the.Java.Memory.Model.Part1/2.pdf Java Memory Model Pragmatics (transcript).pdf 读JSR133笔记 - 十年磨一剑 - ITeye博客.pdf The JSR-133 Cookbook.pdf jsr-133-...
《Java Memory Model》是一篇关于Java内存模型的重要论文,由Jeremy Manson、William Pugh以及Sarita V. Adve共同撰写。该论文主要介绍了Java 5.0版本中更新后的Java内存模型(JMM),并详细阐述了它在多线程程序中...
The next era of malware and security breaches are more sophisticated and targeted, and the volatile memory of a computer is often overlooked or destroyed as part of the incident response process. The ...
Java内存模型(Java Memory Model,简称JMM)是Java虚拟机规范中的一个重要组成部分,它定义了程序中各种变量(线程共享变量)的访问规则,以及在并发环境下变量的存储与读取假设。本文将基于JSR-133规范,深入探讨...
The Art of Memory Forensics 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者...
假如你机器的内存不大,改大该参数的值,会导致MemoryAnalyzer启动时,报错:Failed to create the Java Virtual Machine。 2.当你导出的dump文件的大小大于你配置的1024m(说明1中,提到的配置:-vmargs– Xmx1024m...
1、MemoryAnalyzer使用说明文档/使用指南 2、MemoryAnalyzer 1.8.1下载: Eclipse Memory Analyzer 是一个功能丰富且轻量的 Java 堆内存分析工具,可以用来辅助发现内存泄漏减 少内存占用。 使用 Memory Analyzer 来...
为了更好地评估内存消耗,还可以使用内存分析工具,例如MAT(Memory Analyzer Tool)或YourKit Java Profiler,它们可以深入分析堆转储文件,帮助定位内存占用高的对象和引用链,找出导致内存泄漏的原因。...
本文档提供了Java HotSpot虚拟机(JVM)中内存管理的广泛概述,特别是在Sun公司的Java 2平台标准版(J2SE)5.0版本的发布中。文档描述了可供使用的垃圾收集器(Garbage Collectors),给出了关于如何选择和配置收集...
The next era of malware and security breaches are more sophisticated and targeted, and the volatile memory of a computer is often overlooked or destroyed as part of the incident response process. The ...
Now revised to reflect the innovations of Java 5.0, Goodrich and Tamassia’s Fourth Edition of Data Structures and Algorithms in Java continues to offer accessible coverage of fundamental data ...
《Memory Management in the Java HotSpot™ Virtual Machine》一文深入探讨了Java HotSpot虚拟机中的内存管理机制,这是Java性能优化的关键领域。HotSpot虚拟机是Oracle JDK和JRE的一部分,以其高性能和优化能力而...
The Cambridge Face Memory Test: Results for neurologically intact individuals and an investigation of its validity using inverted face stimuli and prosopagnosic participants
Now revised to reflect the innovations of Java 5.0, Goodrich and Tamassia’s Fourth Edition of Data Structures and Algorithms in Java continues to offer accessible coverage of fundamental data ...
Now revised to reflect the innovations of Java 5.0, Goodrich and Tamassia’s Fourth Edition of Data Structures and Algorithms in Java continues to offer accessible coverage of fundamental data ...
Memory forensics is the art of analyzing computer memory (RAM) to solve digital crimes. As a follow-up to the best seller Malware Analyst's Cookbook, experts in the fields of malware, security, and ...
1. Misconfiguration of Memory Pools:内存池的misconfiguration是最常见的内存问题之一。它可以导致Java应用程序中的内存使用率不均匀,导致应用程序崩溃。 2. Excessive use of Finalizers:Finalizer是一种特殊...
### Top 10 Java Performance Problems #### Introduction 在Java应用程序开发过程中,性能问题是一个常见的挑战。这些问题不仅影响应用的响应时间和资源利用率,还可能影响用户体验和业务效率。本文将详细介绍十个...