南靖县建设局网站,建设网站能解决什么问题,怎么制作美篇教程,幸运星哪家制作公司分析java 线程占用内存本文将为您提供一个教程#xff0c;使您可以确定活动应用程序Java线程中保留了多少Java堆空间 。 将提供来自Oracle Weblogic 10.0生产环境的真实案例研究#xff0c;以使您更好地理解分析过程。 我们还将尝试证明过多的垃圾回收或Java堆空间的内存占用… 分析java 线程占用内存 本文将为您提供一个教程使您可以确定活动应用程序Java线程中保留了多少Java堆空间 。 将提供来自Oracle Weblogic 10.0生产环境的真实案例研究以使您更好地理解分析过程。 我们还将尝试证明过多的垃圾回收或Java堆空间的内存占用问题通常不是由真正的内存泄漏引起的而是由线程执行模式和大量的短期对象引起的。 背景 正如您从我过去的JVM概述文章中可能已经看到的那样Java线程是JVM基础的一部分。 您的Java堆空间内存占用量不仅受静态对象和寿命长的对象的驱动还受寿命短的对象的驱动。 通常会错误地认为OutOfMemoryError问题是由于内存泄漏引起的。 我们经常忽略错误的线程执行模式以及它们在Java堆上“保留”到执行完成的短暂对象。 在这种有问题的情况下 您的“预期”应用程序的短期/无状态对象XMLJSON数据有效载荷等被线程保留的时间过长线程锁争用巨大的数据有效载荷来自远程系统的响应时间慢等。 最终这样的短期对象被垃圾收集器提升为长期对象空间例如OldGen / tenured空间 副作用是这导致OldGen空间快速填充从而增加了Full GC主要集合的频率 根据情况的严重性这可能导致过度的GC垃圾收集JVM暂停时间增加并最终导致OutOfMemoryErrorJava堆空间 您的应用程序现在关闭您现在对正在发生的事情感到困惑 最后您正在考虑增加Java堆或查找内存泄漏……您是否真的走对了 在上述情况下您需要查看线程执行模式并确定每个线程在给定时间保留多少内存。 好了我得到了图片但是线程堆栈的大小呢 避免线程堆栈大小和Java内存保留之间的混淆非常重要。 线程堆栈大小是JVM用于存储每个方法调用的特殊内存空间。 当线程调用方法A时它将调用“推”到堆栈上。 如果方法A调用方法B它也会被压入堆栈。 方法执行完成后调用将“弹出”堆栈。 由于此类线程方法调用而创建的Java对象在Java堆空间上分配。 增大线程堆栈大小绝对不会有任何效果。 处理java.lang.stackoverflowerror或OutOfMemoryError无法创建新的本机线程问题时通常需要调整线程堆栈的大小。 案例研究和问题背景 以下分析是基于我们最近调查的一个实际生产问题。 在用户Web界面进行了一些更改使用Google Web Toolkit和JSON作为数据有效负载之后从Weblogic 10.0生产环境中观察到严重的性能下降。 初步分析确实发现了OutOfMemoryError的几种情况Java堆空间错误以及过多的垃圾回收。 在发生OOM事件后会自动生成Java堆转储文件-XX HeapDumpOnOutOfMemoryError 对verbosegc日志的分析确实确认了32位HotSpot JVM OldGen空间1 GB容量的完全耗尽 在问题发生之前和期间也会生成线程转储快照 当时唯一可以解决的问题是观察到问题时重新启动受影响的Weblogic服务器 最终对变更进行了回滚这确实解决了这种情况 团队首先从引入的新代码中怀疑了内存泄漏问题。 线程转储分析寻找可疑对象… 我们所做的第一步是对生成的线程转储数据进行分析。 线程转储通常会向您显示在Java堆上分配内存的罪魁祸首线程。 它还将揭示试图从远程系统发送和接收数据有效载荷的任何占用线程或阻塞线程。 我们注意到的第一个模式是从Weblogic托管服务器JVM进程观察到的OOM事件和STUCK线程之间具有良好的相关性。 在找到的主线程模式下面找到 10-Dec-2012 1:27:59 oclock PM EST Error BEA-000337[STUCK] ExecuteThread: 22 for queue:weblogic.kernel.Default (self-tuning)has been busy for 672 seconds working on the requestwhich is more than the configured time of 600 seconds. 如您所见以上线程似乎是STUCK或花费很长时间读取和接收来自远程服务器的JSON响应。 一旦找到该模式下一步就是将该发现与JVM堆转储分析相关联并确定这些卡住的线程从Java堆中占用了多少内存。 堆转储分析保留的对象暴露在外 Java堆转储分析是使用MAT执行的。 现在我们将列出不同的分析步骤这些步骤确实使我们可以查明保留的内存大小和源。 1.加载HotSpot JVM堆转储 2.选择HISTOGRAM视图并按“ ExecuteThread”进行过滤 * ExecuteThread是Weblogic内核用于线程创建和执行的Java类* 如您所见这种观点非常明显。 我们可以看到总共创建了210个Weblogic线程。 这些线程保留的内存总量为806 MB。 这对于具有1 GB OldGen空间的32位JVM进程而言非常重要。 仅此观点就告诉我们问题的核心和内存保留源于线程本身。 3.深入研究线程内存占用量分析 下一步是深入研究线程内存保留。 为此只需右键单击ExecuteThread类然后选择列出对象具有传出引用。 如您所见我们能够将线程转储分析中的STUCK线程与堆转储分析中的高内存保留量相关联。 这一发现非常令人惊讶。 4.线程Java局部变量识别 最后的分析步骤确实需要我们扩展一些线程样本并了解内存保留的主要来源。 如您所见此最后的分析步骤确实从根本原因上揭示了巨大的JSON响应数据有效载荷。 该模式还通过线程转储分析在早期公开我们发现一些线程需要很长时间才能读取和接收JSON响应。 数据有效负载占用量巨大的明显症状。 至关重要的是要注意通过局部方法变量创建的短期对象将显示在堆转储分析中。 但是其中一些将仅在其父线程中可见因为这种情况下其他对象未引用它们。 您还需要分析线程堆栈跟踪以识别真正的调用者然后进行代码检查以确认根本原因。 根据这一发现在某些情况下我们的交付团队能够确定最近的JSON错误代码更改正在生成高达45 MB 的巨大JSON数据有效负载。 考虑到该环境正在使用只有1 GB OldGen空间的32位JVM您可以理解只有几个线程足以触发严重的性能下降。 该案例研究清楚地表明了适当的容量规划和Java堆分析的重要性包括从活动应用程序和Java EE容器线程中保留的内存。 其他一切都只是信息 我希望本文能帮助您了解如何结合线程转储和堆转储分析来确定活动线程保留的Java堆内存占用量。 现在如果您不尝试的话本文将仅停留在文字上因此我强烈建议您花一些时间自己学习针对您的应用程序进行的分析过程。 参考 Java Thread保留了我们的JCG合作伙伴 Pierre-Hugues Charbonneau在Java EE支持模式和Java教程博客上进行的内存分析 。 翻译自: https://www.javacodegeeks.com/2012/12/java-thread-retained-memory-analysis.html分析java 线程占用内存