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虚拟内存。 进行完整的根本原因分析将需要此关键数据
  • 不要以为您正在处理操作系统内存容量问题。 查看所有正在运行的进程,并确定您的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/352700.shtml

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

相关文章

Linux makefile 教程 非常详细,且易懂

最近在学习Linux下的C编程,买了一本叫《Linux环境下的C编程指南》读到makefile就越看越迷糊,可能是我的理解能不行。 于是google到了以下这篇文章。通俗易懂。然后把它贴出来,方便学习。 后记,看完发现这篇文章和《Linux环境下的C…

java的string访问某个元素_C#深究.net常用的23种设计模式之访问者模式(Vistor Pattern)...

一、引言在上一篇博文中分享了责任链模式,责任链模式主要应用在系统中的某些功能需要多个对象参与才能完成的场景。在这篇博文中,我将为大家分享我对访问者模式的理解。二、访问者模式介绍2.1 访问者模式的定义访问者模式是封装一些施加于某种数据结构之…

卸载 系统打印服务器,win10系统打印机驱动卸载不掉的方案介绍

win10系统使用久了,好多网友反馈说win10系统打印机驱动卸载不掉的问题,非常不方便。有什么办法可以永久解决win10系统打印机驱动卸载不掉的问题,面对win10系统打印机驱动卸载不掉的图文步骤非常简单,只需要1、开始-设备和打印机&a…

1007

package com.company;import java.util.ArrayList; import java.util.Scanner;public class Main {public static void main(String[] args) {// write your code hereScanner scnew Scanner(System.in);int Nsc.nextInt();int[] numnew int[N];//N以内的所有数int i;ArrayList…

Apache ActiveMQ中的消息级别授权

尽管上一篇文章介绍了“代理级身份验证”,但该博文是关于消息级更严格的授权的。 我在现实生活中的项目中并没有这么精细的授权,但是我想自己做,并为读者提供一个教程,以扩展他们对ActiveMQ中安全性的了解并简化他们的工作。 有…

14章总结

一.lambda表达式 1.lambda表达式简介 lambda表达式不能独立执行,因此必须实现函数式接口,并且会返回一个函数式接口的对象。 语法: ()->结果表达式 参数->结果表达式 (参数1,参数2,...,参数n)->…

一个最简单的Makefile例子(转)

原文地址&#xff1a;http://hi.baidu.com/hellosim/blog/item/42e78341b40c3e8db2b7dce3.html 转载请注明出处 1.hello.c #include <stdio.h> int main() { printf("Hello World!\n"); return 0; } 2.Makefile hello : hello.o cc -o hello h…

python基础知识资料包-Python基础知识总结——史上最全系列

一、数据类型 1、可变数据类型 a.列表(list) 列表的系列函数&#xff1a; ①append():元素的追加&#xff0c;在列表的末尾添加新的值 列表名.append(新增的值) ②insert(下标&#xff0c;值)&#xff1a;在指定下标插入指定的值 列表名.insert(下标&#xff0c;值) ③count(值…

提高速度 - MyEclipse配置

http://jingyan.baidu.com/article/f3ad7d0fddec3b09c3345ba6.html 转载于:https://www.cnblogs.com/7q4w1e/p/9706376.html

暗时间(普通的一种时间概念)

收藏18354暗时间&#xff08;普通的一种时间概念&#xff09;编辑 暗时间简单的说就是思维的时间&#xff0c;也就是没有产生直接成果的时间。一个人走路、买菜、洗脸洗手、坐公车、逛街、出游、吃饭、睡觉&#xff0c;所有这些时间都可以成为“暗时间”&#xff0c;你可以充分…

ZOJ 1586 QS Network

题目链接 QS NetworkTime Limit: 2 Seconds Memory Limit: 65536 KBSunny Cup 2003 - Preliminary Round April 20th, 12:00 - 17:00 Problem E: QS Network In the planet w-503 of galaxy cgb, there is a kind of intelligent creature named QS. QScommunicate with e…

javaone_JavaOne 2012:101种改进Java的方法-开发人员参与为何如此重要

javaoneBruno Souza &#xff0c; Martijn Verburg和Heather Vancura在希尔顿酒店的美国大陆宴会厅4中展示了“ 101种改善Java的方法&#xff1a;开发人员为何如此重要”。 他们将其分为自己最熟悉的领域。 SouJava的创始人兼协调员 Souza谈到了通过用户组的更大参与。 Verberg…

谷歌浏览器flash_谷歌浏览器不支持Flash Player的问题

更新2020.6.10&#xff0c;这个答案更新过方式1&#xff1a;老版谷歌chrome浏览器里输入&#xff1a;chrome://flags/#run-all-flash-in-allow-mode进行设定。方式2&#xff1a;新版谷歌68&#xff0c;69以上版本&#xff0c;chrome浏览器操作方式&#xff1a;新版不再允许保存…

深入理解python之self

首先明确的是self只有在类的方法中才会有&#xff0c;独立的函数或方法是不必带有self的。self在定义类的方法时是必须有的&#xff0c;虽然在调用时不必传入相应的参数。 self名称不是必须的&#xff0c;在python中self不是关键词&#xff0c;你可以定义成a或b或其它名字都可以…

Oracle12c异常关闭后启动PDBORCL(ORA-01033)

这个问题已经困扰了我好几天找解决方案&#xff0c;终于找到&#xff1a; 由于Oracle12c的特殊性&#xff0c;但许多用户并不想在创建用户时前面要加"C##" 那么就要创建PDBORCL数据库&#xff0c;来与Oracle以前的版本保持一致(如Oracle 11g) 可能由于断电或者异常关…

带有Spring Cloud Microservices的JSON Web令牌

在Keyhole&#xff0c;我们已经发布了几个有关微服务的博客 。 我们已经讨论了微服务环境中使用的架构模式&#xff0c;例如服务发现和断路器 。 我们甚至在平台和工具上发布了博客&#xff0c;例如最近关于Service Fabric的博客 。 我们已经介绍过的架构的重要组成部分是围绕…

STC用PCA测量脉宽_教你测量玉手镯圈号及如何轻松快速摘戴玉手镯?

一、如何测量玉手镯的圈号&#xff1f;测量和田玉手镯的圈号并不复杂&#xff0c;自己在家就能轻松搞定哦&#xff01;共有两种方法可选。方法一&#xff1a;游标卡尺法所需工具&#xff1a;游标卡尺具体方法&#xff1a;如照片所示&#xff0c;使用游标卡尺测量手掌最宽处(大拇…

Python中的函数(一)

接触过C语言的朋友对函数这个词肯定非常熟悉&#xff0c;无论在哪门编程语言当中&#xff0c;函数&#xff08;当然在某些语言里称作方法&#xff0c;意义是相同的&#xff09;都扮演着至关重要的角色。今天就来了解一下Python中的函数用法。 一.函数的定义 在某些编程语言当中…

Shell基础命令

它又是一种程序设计语言。作为命令语言&#xff0c;它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令&#xff1b;作为程序设计语言&#xff0c;它定义了各种变量和参数&#xff0c;并提供了许多在高级语言中才具有的控制结构&#xff0c;包括循…

电脑报警5声_电脑故障怎么判断 常见电脑故障诊断方法介绍【详解】

在电脑使用的过程&#xff0c;出现一些电脑故障是在所难免的&#xff0c;很多小伙伴对一些常见电脑故障诊断的方法不是很了解&#xff0c;不知道自己电脑出现的这些故障 究竟是什么原因造成的 。关于软件故障有很多种可能性&#xff0c;一般都是比较容易解决的&#xff0c;今天…