首页 > 系统相关 >一次JVM内存溢出的排查经过

一次JVM内存溢出的排查经过

时间:2023-08-03 19:39:14浏览次数:30  
标签:java Thread 排查 线程 内存 JVM new public



文章目录

  • 一、背景
  • 二、解决办法
  • 三、总结


一、背景

高峰将至,系统访问量进入高峰期。随之系统出现了异常:java.lang.OutOfMemoryError: unable to create new native thread。在解决这个问题中,尝试了各种方法,最后竟然是因为它…

二、解决办法

1、 关于这个问题,一开始猜想是因消息队列(activemq)引起的,因为处理数据较多,开启的线程数较多导致,因此对MQ搭建了集群。

MQ集群搭建方法:

但是搭建集群后发现,并不是,问题依旧。

继续…

2、 接下来怀疑是系统里开的线程数太多,在优化后,问题仍然存在。

继续......

3、 内存调优,减小xss值、JVM内存,仍然解决不了。

继续......

4、 几番周测,在整理思路后,决定首要任务就是如何重现该问题,于是编写测试程序,测试出操作系统最大能够创建的线程数:

import java.util.concurrent.CountDownLatch;

public class TestNativeOutOfMemoryError {

    public static void main(String[] args) {

        for (int i = 0;; i++) {
            System.out.println("i = " + i);
            new Thread(new HoldThread()).start();
        }
    }

}

class HoldThread extends Thread {
    CountDownLatch cdl = new CountDownLatch(1);

    public HoldThread() {
        this.setDaemon(true);
    }

    public void run() {
        try {
            cdl.await();
        } catch (InterruptedException e) {
        }
    }
}

运行后:

i = 982
  Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
      at java.lang.Thread.start0(Native Method)
      at java.lang.Thread.start(Thread.java:597)
      at TestNativeOutOfMemoryError.main(TestNativeOutOfMemoryError.java:20)

问题重现,在反复运行几次后发现,生产系统最大只能创建980多个线程,生产系统操作系统64位centos,jdk1.7,64G内存。而我本地PC电脑都可以创建2500左右。

感觉原因快找到了,切换到运行账户使用命令:

$ su Bst118

  $ ulimit -u

  $ 1024

生产上所有程序都是在Bst118账户下运行,于是查看该账户下所有的线程数总和为950,也即是说,随时都可能会超过1024,导致内存溢出。查看看进程当前运行的线程数命令为:pstree -p 3660 | wc -l

原因找到,操作系统对运行程序的账户有最大线程数限制。

$ vim /etc/security/limits.d/90-nproc.conf

打开后发现除了root,其他账户都限制在1024个。

于是增加一条:

Bst118     soft    nproc     20000

为什么设置为20000,因为测试后发现,在运行到35000左右,系统就报内存溢出了,操作系统所有命令都不能使用,因此将程序最大线程数限制在20000。

修改后再没出现内存溢出错误。问题解决。

三、总结

1、经过总结,在遇到问题后,不能盲目的到处修改,首先要做的就是重现问题,顺藤摸瓜,逐步的找出根本原因。


标签:java,Thread,排查,线程,内存,JVM,new,public
From: https://blog.51cto.com/u_13693015/6952262

相关文章

  • JAVA系列之JVM内存调优
    文章目录一、前提二、JVM内存结构1、栈内存2、堆内存3、永久代(元空间)三、JVM常用参数1、堆大小设置2、垃圾回收器选择2.1吞吐量优先的并行收集器2.2响应时间优先的并发收集器3、其他辅助配置四、内存溢出排查1、元空间溢出(java.lang.OutOfMemoryError:Metaspace)2、栈深度不够(ja......
  • JAVA系列之内存模型(JMM)
    文章目录一、简介二、硬件内存模型1、高速缓存和缓存一致性2、CPU三级缓存3、缓存一致性4、Java线程与CPU5、指令重排序三、Java内存模型1、Java内存模型概念2、Java内存模型与硬件内存模型之间的关系3、Java内存模型作用4、Java内存模型的同步操作与规则5、Java内存模型三大特性5......
  • 怎么设置centos限定redis使用的内存
    1、Redis-Cluster集群2、怎么设置centos限定redis使用的内存3、高性能高并发网站架构,教你搭建Redis5缓存集群4、Redis-Cluster5、「实用教程」在配备持久内存的实例上部署Redis应用Redis-Cluster集群1、连接如下https://redis.io/topics/cluster-tutorial以下步骤是在一......
  • 《深入理解Java虚拟机》读书笔记:Java内存区域
    Java内存区域包含程序计数器、虚拟机栈、本地方法栈、Java堆、方法区五个区域。运行时数据区分类 Java内存区域 一、程序计数器程序计数器(ProgramCounterRegister)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的信号指示器。字节码解释器工作时就是通过......
  • sqlserver没有足够的内存继续执行程序
      需求,导出的数据库表,数据生成的sql脚本很大运行sql脚本内存不足。 解决方法:一,通过sqlcmd工具来执行大的脚本1,用管理员身份打开命令行工具有些可能要进入到cdC:\ProgramFiles\MicrosoftSQLServer\100\Tools\Binn目录运行sqlcmd2,运行 sqlcmd-S.-Usa-P123......
  • 国标GB28181安防视频平台EasyGBS大批量通道接入后,创建角色接口未响应的排查
    国标GB28181协议视频平台EasyGBS是基于国标GB28181协议的视频云服务平台,支持多路设备同时接入,并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。平台可提供视频监控直播、云端录像、云存储、检索回放、智能告警、语音对讲、平台级联等功能,在视频能力上,GB2818......
  • JVM垃圾回收
    JVM垃圾回收1.概述JVM(Java虚拟机)的垃圾回收是自动管理内存的过程,用于回收不再使用的对象并释放内存资源。早在1960年,第一门开始使用内存动态分配和垃圾收集技术的Lisp语言诞生。这种自动化的内存管理机制极大地减轻了开发人员对手动释放内存的负担,提高了开发效率。1.1.什么是垃......
  • TSINGSEE青犀视频安防监控EasyCVR视频汇聚平台电子地图定位偏移的排查与解决
    安防监控EasyCVR视频汇聚综合管理平台具有强大的数据接入、处理及分发能力,平台可提供视频监控直播、云端录像、云存储、录像检索与回看、告警上报与查询、平台级联、云台控制、语音对讲、电子地图、轨迹跟踪、H.265自动转码等视频能力。在视频监控管理平台TSINGSEE青犀视频EasyCVR......
  • 排查问题中想当然,简单问题复杂化
    用户要求A点访问H点服务器,测试发现ping和telnet端口均不通根据tracert跟踪路由发现只能到E点交换机已知H点服务器在开发测试网络,E点到H点经过F点防火墙和开发核心交换机于是在F点防火墙配置到A点的静态路由和检查防火墙策略均OK但是tracert跟踪路由仍然只能到E点交换机及访问H点服......
  • Java应用内存溢出排查
    Java应用内存溢出&CPU占满排查1.获取异常进程IDtop-m2.保存堆快照jmap-dump:format=b,file=/data/logdir/dump.hprof[PID]3.观察GC状况#采样10次(2秒/次)后结束,5行1组输出jstat-gcutil-t-h5[PID]2s104.获取进程内线程详情,观察异常线程IDtop-......