OutOfMemoryError:无法创建新的本机线程–问题神秘化

正如您从我以前的教程和案例研究中可能已经看到的那样,要确定和解决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本机代码无法从操作系统(Solaris,Linux,MAC,Windows等)创建新的“本机”线程。
我们可以从如下的OpenJDK 1.6和1.7实现中清楚地看到此逻辑:

不幸的是,在这一点上,您不会得到比该错误更详细的信息,没有迹象表明为什么JVM无法从OS创建新线程…

HotSpot JVM:32位还是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 EB(1600万TB)

如您所见,如果您为32位JVM进程分配了较大的Java Heap(2 GB +),则本机内存空间容量将自动减少,这为JVM本机内存分配失败打开了方便之门。
对于64位JVM进程,从JVM C堆的角度来看,您主要关心的是操作系统物理,虚拟和交换内存的容量和可用性。

好的,但是本机内存如何影响Java线程的创建?

现在回到我们的主要问题。 另一个需要了解的JVM基本方面是,从JVM创建的Java线程需要来自操作系统的本机内存。 现在,您应该开始了解问题的根源…
高级线程创建过程如下:

  • 从Java程序和JDK请求一个新的Java线程
  • 然后,JVM本机代码尝试从OS创建一个新的本机线程
  • 然后,操作系统尝试根据包括线程堆栈大小在内的属性创建一个新的本机线程。 然后,将本地内存从OS分配(保留)到Java进程本地内存空间; 假设该进程具有足够的地址空间(例如32位进程)来满足请求
  • 如果32位Java进程大小耗尽了其内存地址空间,例如2 GB,3 GB或4 GB进程大小限制,则OS将拒绝任何进一步的本机线程和内存分配
  • 如果操作系统的虚拟内存已耗尽(包括Solaris交换空间耗尽),则操作系统还将拒绝任何进一步的线程和本机内存分配,因为对堆栈的线程访问可能会产生SIGBUS错误,从而使JVM崩溃* http://bugs.sun .com / view_bug.do?bug_id = 6302804

综上所述:

  • 创建Java线程需要从OS获得可用的本机内存。 适用于32位和64位JVM进程
  • 对于32位JVM,创建Java线程还需要C-Heap或进程地址空间中可用的内存

问题诊断

既然您对本地内存和JVM线程的创建有了更好的了解,现在是时候来看看您的问题了。 首先,我建议您遵循以下分析方法:

  1. 确定您使用的是HotSpot 32位还是64位JVM
  2. 观察到问题时,请进行JVM线程转储,并确定有多少个活动线程
  3. 在OOM问题复制之前和期间密切监视Java进程大小利用率
  4. 在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), pid=2290, tid=27
#  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, id=27, stack(0x65380000,0x65400000)]Stack: [0x65380000,0x65400000],  sp=0x653fd758,  free space=501k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 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虚拟内存。 进行完整的根本原因分析将需要此关键数据
  • 不要以为您正在处理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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371508.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

求10以内平均数的c语言,求助 给小学生出题,自己选加减乘除 做10题 10以内的数 然后统计分...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include #include void Menu(void){printf("1,加法 2,减法 3,乘法 4,除法 5,退出\n");printf("请选择题目类型:");}int Plus(void){int a, b;a rand() % 10 1;b rand() % 10 1;printf("%-2…

linux常用命令大全(转)好东西要分享

1、ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文件,包含以.开始的隐藏文件 ls -A 列出除.及.…

Cobertura和Maven:集成和单元测试的代码覆盖率

在姜黄项目中,我们每晚维护一个仪表板。 在仪表板上,我们收集有关项目的统计信息,包括代码覆盖率,findbugs分析和其他指标。 我们一直在使用Maven EMMA插件来提供代码覆盖,但是遇到了EMMA问题。 在对类进行检测后&…

二分图之匈牙利算法模版

1 /*2 匈牙利算法模版邻接表版3 最大匹配问题4 时间复杂度&#xff1a;O (nm)5 */6 #include <cstdio>7 #include <vector>8 #include <cstring>9 using namespace std; 10 const int maxn 505; 11 vector<int> v[maxn];//x v[i][j]表示i可以与x匹配…

android 字体描边实现,android文字描边功能的实现

这里也要简单说一下&#xff0c;这些小模块并不是我原创&#xff0c;也是当时查资料找到的&#xff0c;由于时间比较久&#xff0c;原文链接已经忘记了&#xff0c;所以这里就不列出引用链接了。不过这些代码我都修改、完善过&#xff0c;也添加了一些注释&#xff0c;希望对大…

Factorial vs Power

题意 输入a&#xff0c;找到满足n!>a^n 最小的n。 数据 第一行T(1 < T < 1e5)&#xff0c;表示测试样例数.(2 < a < 1e6)。 输入 3 2 3 4 输出 4 7 9 这个东西一看就知道是二分求解的&#xff0c;但是我们还是不知道怎么求的&#xff0c;我们可以吧他们取对数然…

评论:Arun Gupta撰写的“ Java EE 6 Pocket Guide”

这是我很高兴写的评论。 我的朋友阿伦&#xff08;Arun&#xff09;发布了Java EE 6袖珍指南&#xff0c;该指南将在您订购时尽早提供。 我很早就知道这本书&#xff0c;因为我很乐意对其进行回顾&#xff0c;也感谢有机会为本书做出一点贡献&#xff01; Kindle版本已经可用&a…

双android手机同步工具,手机同步软件Android Manager使用图文教程

类型&#xff1a;手机工具大小&#xff1a;23.6M语言&#xff1a;繁体 评分&#xff1a;6.6标签&#xff1a;立即下载Android Manager 可透过五个简单的步骤设定&#xff1a;步骤一. 在计算机上安装 Android Manager请点选以下之下载按钮或直接于计算机上输入下载网址&#xff…

Camel:构建基于消息的应用程序

这是一篇长文章&#xff0c;包含三个单独的主题&#xff1a; Java的Apache Camel入门 使用CamelRunner改善路线的启动 使用Camel构建基于消息的应用程序 但是&#xff0c;由于我准备了包含所有这些材料的camel-demo-1.0.0-SNAPSHOT-project.zip &#xff0c;因此我认为将它们…

android 网易item广告,Android仿网易严选商品详情页

仿照网易严选商品详情页面&#xff0c;整个页面分为两个部分&#xff0c;上面一部分是Native的ScrollView&#xff0c;下面一部分则是WebView&#xff0c;其目的是为了可以进行分步加载。滑动到ScrollView底部时&#xff0c;继续向上拖动&#xff0c;可以加载下面的WebView部分…

freemarker,数字,日期,布尔值常用的函数

${3.4?floor} ${3.4?ceiling} ${3.45?round} ${3.45?rtf} ${3.458?string("0.##")} ${3.42?string.percent} ${3.42?string.currency} ${date?string("yyyy-MM-dd")} ${date?date} ${date?time} ${date?datetime}${true?c} ${true?string} ${…

mysql联合索引与Where子句优化浅析

问题描述&#xff1a;把排序、条件等一个一个去除来做测试&#xff0c;结果发现问题就出在排序部分&#xff0c;去除排序时&#xff0c;执行时间由原来的48秒变成0.3x秒。于是&#xff0c;把涉及排序的字段组成一个联合索引alter table xx add index indexname(x1,x2,x3)&#…

有效使用Eclipse的热门提示

以下是一些技巧&#xff0c;可以帮助您避免潜在的问题并在使用Eclipse时提高工作效率。 避免安装问题 切勿在旧版本之上安装新版本的Eclipse。 首先重命名旧版本&#xff0c;将其移开&#xff0c;然后将新版本解压缩到干净的目录中。 恢复混乱的工作空间 对于许多开发人员来…

android拍照截图组件,Android截图命令screencap与视频录制命令screenrecord(示例代码)...

查看帮助命令[email protected] ~$ adb shell screencap -vscreencap: invalid option -- vusage: screencap [-hp] [-d display-id] [FILENAME]-h: this message-p: save the file as a png.-d: specify the display id to capture, default 0.If FILENAME ends with .png it …

usaco 2017 February platinum

1.一条路&#xff0c;两边都是一个1到n的全排列&#xff0c;可以把其中一个全排列的起始位置改变&#xff08;比如123可以变成231或者312&#xff09; 然后把相同的数连起来&#xff0c;求小交叉数。 先算一下交叉数&#xff0c;然后直接一步步移动&#xff0c;O1更新一下状态就…

Hessian 源码简单分析

Hessian 源码简单分析 Hessian 是一个rpc框架&#xff0c; 我们需要先写一个服务端&#xff0c; 然后在客户端远程的调用它即可。 服务端&#xff1a; 服务端通常和spring 做集成。 首先写一个接口&#xff1a; public interface HelloService { void sayHello(String n…

Java开发人员应该知道的三件事

对于那些长期关注JavaOne 2012会议的读者来说&#xff0c;这是一篇有趣的文章。 我最近对Java冠军Heinz Kabutz的采访引起了我的注意&#xff1b; 包括他的Java内存难题程序&#xff0c;从Java内存管理的角度来看&#xff0c;这很有启发性。 采访中有一个特别的部分吸引了我的注…

android怎么垂直居中且靠右,placeholder 靠右垂直居中/位置兼容

1.input输入框文字靠右垂直居中。2.placehoder提示同样靠右垂直居中。( placeholder是HTML5 input的新属性&#xff0c;英文意思是占位符&#xff0c;它一般表示input输入框的默认提示值。)css代码input {text-align: right;font-size:0.3rem;width:100%;height:0.78rem;line-…

Python-Matplotlib 18 注释

Python-Matplotlib 18 注释 EG1: import numpy as np import matplotlib.pyplot as plty np.arange(-5, 6,1) plt.plot(y, y*y) plt.annotate(Annotate , xy(0,1) , xytext(0,5) ,arrowpropsdict(facecolorr , frac0.2 ))plt.show()转载于:https://www.cnblogs.com/zsr0401/p/…

while和for循环

循环结构图&#xff1a; 循环结构主要分为两种&#xff1a;有while和for两种循环&#xff0c;while又分为do{...}while和while{...},do...while表示先执行后判断&#xff0c;而while循坏表示先判断后执行&#xff0c;如果循环条件都不满足的情况下&#xff0c;do...while至少执…