龙岗网站优化,凡客诚品是什么牌子,使用socket登陆wordpress源码,网站开发主要创新点正如您从我以前的教程和案例研究中可能已经看到的那样#xff0c;要确定和解决Java Heap Space OutOfMemoryError问题可能很复杂。 我从Java EE生产系统中观察到的常见问题之一是OutOfMemoryError#xff1a;无法创建新的本机线程#xff1b; HotSpot JVM无法进一步创建新的… 正如您从我以前的教程和案例研究中可能已经看到的那样要确定和解决Java Heap Space OutOfMemoryError问题可能很复杂。 我从Java EE生产系统中观察到的常见问题之一是OutOfMemoryError无法创建新的本机线程 HotSpot JVM无法进一步创建新的Java线程时引发的错误。 本文将重温此HotSpot VM错误并为您提供建议和解决策略。 如果您不熟悉HotSpot JVM我首先建议您从高角度查看其内部HotSpot JVM内存空间 。 为了使您了解与本机C-Heap内存空间有关的OutOfMemoryError问题此知识很重要。 OutOfMemoryError无法创建新的本机线程–这是什么 让我们从一个基本的解释开始。 当内部JVM本机代码无法创建新的Java线程时将引发此HotSpot JVM错误。 更准确地说这意味着JVM本机代码无法从操作系统SolarisLinuxMACWindows等创建新的“本机”线程。 我们可以从如下的OpenJDK 1.6和1.7实现中清楚地看到此逻辑 不幸的是在这一点上您不会得到比该错误更详细的信息没有迹象表明为什么JVM无法从OS创建新线程… HotSpot JVM32位还是64位 在进行进一步分析之前必须从Java或Java EE环境中确定的一个基本事实是您正在使用的HotSpot VM版本是32位还是64位。 为什么这么重要 您将很快了解到这个JVM问题通常与本机内存耗尽有关。 在JVM进程或OS级别。 目前请记住 理论上一个32位JVM进程允许增长到4 GB在某些较旧的32位Windows版本上甚至更低。 对于32位JVM进程C堆正在与Java堆和PermGen空间竞争 例如C堆容量 2-4 GB – Java堆大小 -Xms-Xmx– PermGen大小-XX MaxPermSize 从理论上讲允许使用64位JVM进程使用大多数可用的OS虚拟内存或最多16 EB1600万TB 如您所见如果您为32位JVM进程分配了较大的Java Heap2 GB 则本机内存空间容量将自动减少这为JVM本机内存分配失败打开了方便之门。 对于64位JVM进程从JVM C堆的角度来看您主要关心的是操作系统物理虚拟和交换内存的容量和可用性。 好的但是本机内存如何影响Java线程的创建 现在回到我们的主要问题。 另一个需要了解的JVM基本方面是从JVM创建的Java线程需要来自操作系统的本机内存。 现在您应该开始了解问题的根源… 高级线程创建过程如下 从Java程序和JDK请求一个新的Java线程 然后JVM本机代码尝试从OS创建一个新的本机线程 然后操作系统尝试根据包括线程堆栈大小在内的属性创建一个新的本机线程。 然后将本地内存从OS分配保留到Java进程本地内存空间 假设该进程具有足够的地址空间例如32位进程来满足请求 如果32位Java进程大小耗尽了其内存地址空间例如2 GB3 GB或4 GB进程大小限制则OS将拒绝任何进一步的本机线程和内存分配 如果操作系统的虚拟内存已耗尽包括Solaris交换空间耗尽则操作系统还将拒绝任何进一步的线程和本机内存分配因为对堆栈的线程访问会生成SIGBUS错误从而使JVM崩溃* http//bugs.sun .com / view_bug.dobug_id 6302804 综上所述 创建Java线程需要从OS获得可用的本机内存。 适用于32位和64位JVM进程 对于32位JVM创建Java线程还需要C-Heap或进程地址空间中可用的内存 问题诊断 既然您对本地内存和JVM线程的创建有了更好的了解现在是时候看看您的问题了。 首先我建议您遵循以下分析方法 确定您使用的是HotSpot 32位还是64位JVM 观察到问题时请进行JVM线程转储并确定有多少个活动线程 在OOM问题复制之前和期间密切监视Java进程大小利用率 在OOM问题复制之前和期间密切监视OS虚拟内存利用率 如果使用Solaris OS则包括交换内存空间利用率 根据上述正确收集数据将使您可以收集适当的数据点从而进行第一级调查。 下一步将是研究可能的问题模式并确定哪种模式适用于您的问题案例。 问题模式1 – C堆耗尽32位JVM 根据我的经验OutOfMemoryError对于32位JVM进程无法创建新的本机线程是很常见的。 与C堆容量相比创建太多线程时通常会观察到此问题。 JVM线程转储分析和Java进程大小监视将使您确定是否是原因。 问题模式2 –操作系统虚拟内存耗尽64位JVM 在这种情况下操作系统虚拟内存已完全耗尽。 这可能是由于一些64位JVM进程占用大量内存例如10 GB 和/或其他占用大量内存的流氓进程。 同样Java进程大小和OS虚拟内存监视将使您确定是否是原因。 问题模式3 –操作系统虚拟内存耗尽32位JVM 第三种情况不那么频繁但仍然可以观察到。 诊断可能会稍微复杂一些但是关键的分析点是确定哪些进程导致了OS虚拟内存的全部耗尽。 您的32位JVM进程可能是源也可能是受害者例如使用大多数OS虚拟内存的流氓进程并阻止您的32位JVM进程为其线程创建过程保留更多的本机内存。 请注意当Solaris上的OS虚拟内存或交换空间用尽时此问题也可能表现为完全JVM崩溃如下示例所示。 #
# A fatal error has been detected by the Java Runtime Environment:
#
# java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate. Out of swap space?
#
# Internal Error (allocation.cpp:166), pid2290, tid27
# Error: ChunkPool::allocate
#
# JRE version: 6.0_24-b07
# Java VM: Java HotSpot(TM) Server VM (19.1-b02 mixed mode solaris-sparc )
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#--------------- T H R E A D ---------------Current thread (0x003fa800): JavaThread CompilerThread1 daemon [_thread_in_native, id27, stack(0x65380000,0x65400000)]Stack: [0x65380000,0x65400000], sp0x653fd758, free space501k
Native frames: (Jcompiled Java code, jinterpreted, VvVM code, Cnative code)
……………… 本机内存耗尽是症状还是根本原因 现在您已经了解了您的问题并且知道了要处理的问题模式。 您现在准备提供解决问题的建议……是吗 您的工作尚未完成请记住此JVM OOM事件通常只是问题实际根源的“症状”。 根本原因通常更加深入因此在向客户提供建议之前我建议您确实进行更深入的分析。 您要做的最后一件事就是简单地解决并掩盖症状。 仅当您对根本原因和生产环境容量要求有充分了解后才应考虑采用诸如增加操作系统物理/虚拟内存或将所有JVM进程升级到64位之类的解决方案。 下一个要回答的基本问题是发生OutOfMemoryError时有多少个线程处于活动状态 根据我在Java EE生产系统中的经验最常见的根本原因实际上是应用程序和/或Java EE容器在遇到不满意的路径例如卡在远程IO调用中的线程时试图在给定时间创建太多线程在这种情况下当尝试满足传入的客户端请求时Java EE容器可能开始创建太多线程从而增加了C堆和本机内存分配的压力。 最重要的是在责怪JVM之前请执行尽职调查并确定是否要处理应用程序或Java EE容器线程调优问题是根本原因。 一旦了解并解决了根本原因线程创建的根源便可以调整JVM和OS内存容量以使其更具容错能力并更好地“生存”这些突发的线程激增方案。 建议 首先执行JVM线程转储分析并确定所有活动线程的源与已建立的基准。 确定是什么原因导致您的Java应用程序或Java EE容器在发生故障时创建了如此多的线程 请确保您的监视工具密切监视Java VM进程大小和OS虚拟内存。 进行完整的根本原因分析将需要此关键数据 不要以为您正在处理操作系统内存容量问题。 查看所有正在运行的进程并确定您的JVM进程实际上是问题的根源还是其他消耗所有虚拟内存的进程的受害者 重新访问Java EE容器线程配置和JVM线程堆栈大小。 确定是否允许Java EE容器创建比JVM进程和/或OS可以处理的线程更多的线程 确定您的32位JVM的Java堆大小是否太大从而阻止JVM创建足够的线程来满足客户端请求。 在这种情况下您将不得不考虑减小Java堆大小如果可能垂直扩展或升级到64位JVM。 救援能力规划分析 正如您从我以前关于Java EE企业性能问题的十大原因的文章中可能已经看到的那样缺乏容量规划分析通常是问题的根源。 任何全面的负载和性能测试活动都应正确确定生产环境的Java EE容器线程JVM和OS本机内存需求 包括“不满意”路径的影响测量。 这种方法将使您的生产环境避免此类问题从长远来看可导致更好的系统可伸缩性和稳定性。 别忘了分享 参考 OutOfMemoryError无法创建新的本机线程– Java EE支持模式和Java教程博客上的JCG合作伙伴 Pierre-Hugues Charbonneau 揭开了神秘的面纱 。 翻译自: https://www.javacodegeeks.com/2012/09/outofmemoryerror-unable-to-create-new.html