【jvm】记一次hive堆heap内存溢出的排查
先看下java的内存模型
监控jvm工具:visualVM 摘录一下内容:
由c++开发的jvm,它巧妙地设计了java的设计理念——即万物皆对象。并设计了这些对象应该如何存储,如何调用,并通过不断迭代设计让对象的存储和回收,执行更加合理,下图是jvm的发展历程。
也许开发者未必精通jvm,但对jvm的深入了解可以对开发,排错,调优有非常大的帮助。这里给出最基本的 jvm 入门知识,也是你监控 jvm并期待通过分析jvm来排错调优所必要的基础知识:
- 堆(Heap):
堆是用于存储对象实例的内存区域。在堆中分配的对象包括通过 new 关键字创建的对象以及数组。
所有线程共享堆,但每个对象都有一个标识它的引用。 - 栈(Stack):
栈用于存储方法的局部变量、操作数栈、方法返回地址等。每个线程都有自己的栈。
每个方法在执行时都会创建一个栈帧,栈帧包含了该方法的局部变量表、操作数栈、动态链接、方法返回地址等信息。 - 程序计数器(Program Counter):
程序计数器是每个线程私有的,用于存储当前线程执行的字节码指令的地址或索引。
在多线程环境下,程序计数器用于记录每个线程执行的位置,确保线程切换后能够恢复到正确的执行位置。 - 本地方法栈(Native Method Stack):
本地方法栈类似于栈,但用于执行本地方法(非 Java 语言编写的方法)。
本地方法栈的实现和栈类似,但用于执行本地代码。 - 元空间(Metaspace):
元空间是 JDK 8+ 版本中引入的(替代原来的方法区),使用本机内存存储类的元信息,包括类的结构信息、静态变量
、方法信息等。
查看hive日志
日志:hive-server2.out
,注意不是:hiveserver2.log
2024-09-10 20:21:35,765 HiveServer2-Background-Pool: Thread-13637 ERROR Unable to create Appender of type HushableMutableRandomAccess
java.lang.OutOfMemoryError: Java heap space
Dumping heap to /var/de_log/hive/java_pid36821.hprof ...
Heap dump file created [18346979563 bytes in 27.401 secs]
Terminating due to java.lang.OutOfMemoryError: Java heap space
可以看到发生了OOM的问题OutOfMemoryError,堆heap内存溢出了。
获取hive内存溢出时候的内存快照hprof
hiveserver2日志文件夹内执行:grep OutOfMemory ./hiveserver2-gc.log*
得到如下内容:
./hiveserver2-gc.log.0:CommandLine flags: -XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/xxx/hive/
参数具体意义参考:-XX:+HeapDumpOnOutOfMemoryError
根据/xxx/hive/
和发生hiveserver2 terminate的时间,找到jvm导出的hprof文件,hprof文件大约有17GB。此文件就是发生OutOfMemoryError时刻的内存快照,很大也压缩不了。
ls -lh
-rw------- 1 hive hadoop 17G Sep 9 23:06 java_pid24619.hprof
使用工具分析hprof文件
工具一VisualVM:
此工具是jdk自带的,一般在JAVA_HOME/bin/jvisualvm.exe在win下直接运行就可以了。
载入hprof
文件在就会的都如下信息:
基本信息:生成的日期: Tue Sep 10 20:30:14 CST 2024文件: D:\java_pid123345.hprof\java_pid12345.hprof文件大小: 17,497 MB字节总数: 18,231,897,382类总数: 23,546实例总数: 11,253,335类加载器: 1,354垃圾回收根节点: 11,647等待结束的暂挂对象数: 0在出现 OutOfMemoryError 异常错误时进行了堆转储导致 OutOfMemoryError 异常错误的线程: HiveServer2-Background-Pool: Thread-12410
点击 HiveServer2-Background-Pool: Thread-12410
超链接就是展示实际进程的调用栈:
"HiveServer2-Background-Pool: Thread-12410" prio=5 tid=12410 RUNNABLEat java.lang.OutOfMemoryError.<init>(OutOfMemoryError.java:48)at org.apache.thrift.protocol.TBinaryProtocol.readStringBody(TBinaryProtocol.java:379)at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:230)at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:77)at org.apache.hadoop.hive.metastore.api.ThriftHiveMetastore$Client.recv_get_database(ThriftHiveMetastore.java:770)Local Variable: org.apache.hadoop.hive.metastore.api.ThriftHiveMetastore$get_database_result#166at org.apache.hadoop.hive.metastore.api.ThriftHiveMetastore$Client.get_database(ThriftHiveMetastore.java:757)at org.apache.hadoop.hive.metastore.HiveMetaStoreClient.getDatabase(HiveMetaStoreClient.java:1523)
从HiveMetaStoreClient.getDatabase
可以发现是hms读取database信息造成的。
工具二mat:
内存溢出怎么排查?分析思路大概都是这样的吧
官网地址:
mat工具地址
注意下载时候选择版本,mat和jdk有一定搭配关系。
(1)可以在overview 下,点击
Leak Suspects
即可执行可疑分析。
在Problem Suspect
项目下是分析的可疑项,
The thread org.apache.hive.service.server.ThreadWithGarbageCleanup @ 0x2d79ff8d8 HiveServer2-Background-Pool: Thread-13828 keeps local variables with total size 1,936,085,120 (10.77%) bytes.
The memory is accumulated in one instance of "byte[]" loaded by "<system class loader>".
The stacktrace of this Thread is available. See stacktrace.Keywords
byte[]Details »
可以看到是org.apache.hive.service.server.ThreadWithGarbageCleanup @ 0x2d79ff8d8
这个进程出现问题了。
(2)查看Histogram
列表项目:
Class Name| Objects | Shallow Heap | Retained Heap
---------------------------------------------------------
byte[] | 130,780 | 17,442,187,032 | >= 17,442,187,032
---------------------------------------------------------
可以根据Retained Heap或者Shallow Heap看到排名第一的是byte[]大约有,17,442,187,032/1024/1024/1024=16.24GB。 17442187032/18346979563=95%,byte[]
占到线程内存的比例很高。
(3)查看thread overview
根据thread名称找到以
0x2d79ff8d8
结尾的thread。
先看最上边的内容,这和java日志调用栈展示的顺序是一致的,最后执行的在最上展示,可以看到java.io.BufferedInputStream.read
读取进本地1,935,998,992/1024/1024/1024=1.8GB内容。
Object / Stack Frame |Name| Shallow Heap | Retained Heap |Context Class Loader|Is Daemon
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
at java.io.BufferedInputStream.read([BII)I (BufferedInputStream.java:336) | | | | |
|- <local> java.io.BufferedInputStream @ 0x2c3ebe9b0 Busy Monitor | | 40 | 40 | |
|- <local> byte[1935998976] @ 0x697000000 ...................................................................................................................................................................................................................................................................| | 1,935,998,992 | 1,935,998,992 | |
'- Total: 2 entries | | | | |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
再看更远的内容,可见ThriftHiveMetastore$Client.recv_get_database()
可以知道读取此内容是由于hive metastore尝试获取database信息引发的。如果是自己写的程序,再往下找一般就能找到是自己的那个类的哪行代码触发的了。
Object / Stack Frame |Name | Shallow Heap | Retained Heap |Context Class Loader |Is Daemon
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
org.apache.hive.service.server.ThreadWithGarbageCleanup @ 0x2d79ff8d8 |HiveServer2-Background-Pool: Thread-13828| 128 | 1,936,085,120 |org.apache.hadoop.hive.ql.exec.UDFClassLoader @ 0x2d397cbc0|false
|- at java.io.BufferedInputStream.read([BII)I (BufferedInputStream.java:336) | | | | |
|- at org.apache.thrift.transport.TIOStreamTransport.read([BII)I (TIOStreamTransport.java:127) | | | | |
|- at org.apache.thrift.transport.TTransport.readAll([BII)I (TTransport.java:86) | | | | |
|- at org.apache.thrift.transport.TSaslTransport.readFrame()V (TSaslTransport.java:458) | | | | |
|- at org.apache.thrift.transport.TSaslTransport.read([BII)I (TSaslTransport.java:433) | | | | |
|- at org.apache.thrift.transport.TSaslClientTransport.read([BII)I (TSaslClientTransport.java:37) | | | | |
|- at org.apache.thrift.transport.TTransport.readAll([BII)I (TTransport.java:86) | | | | |
|- at org.apache.hadoop.hive.thrift.TFilterTransport.readAll([BII)I (TFilterTransport.java:62) | | | | |
|- at org.apache.thrift.protocol.TBinaryProtocol.readAll([BII)I (TBinaryProtocol.java:429) | | | | |
|- at org.apache.thrift.protocol.TBinaryProtocol.readI32()I (TBinaryProtocol.java:318) | | | | |
|- at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin()Lorg/apache/thrift/protocol/TMessage; (TBinaryProtocol.java:219) | | | | |
|- at org.apache.thrift.TServiceClient.receiveBase(Lorg/apache/thrift/TBase;Ljava/lang/String;)V (TServiceClient.java:77) | | | | |
|- at org.apache.hadoop.hive.metastore.api.ThriftHiveMetastore$Client.recv_get_database()Lorg/apache/hadoop/hive/metastore/api/Database; (ThriftHiveMetastore.java:770)| | | | |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
问题根因
程序发生oom的问题找到了,自己hive插件程序(随hiveserver2的sql任务启动)尝试通过hms读取database信息,但这个信息非常大,每个hive sql任务都会触发自己hive插件
从而造成多SQL同时执行的时候内存急剧膨胀,发生oom问题。
相关文章:

【jvm】记一次hive堆heap内存溢出的排查
先看下java的内存模型 监控jvm工具:visualVM 摘录一下内容: 由c开发的jvm,它巧妙地设计了java的设计理念——即万物皆对象。并设计了这些对象应该如何存储,如何调用,并通过不断迭代设计让对象的存储和回收࿰…...

编译运行 webAssembly(wasm)
环境准备: lunix下docker 参考https://hub.docker.com/r/emscripten/emsdk 拉编译环境 docker pull emscripten/emsdk 编译 随便找个目录,敲下面命令,编译一个webAssembly 程序 # create helloworld.cpp cat << EOF > hellowo…...
Linux bash 关联数组
目录 一. 关联数组定义二. 访问关联数组三. 元素的添加与删除四. 键值对的获取与遍历五. 实际应用5.1 读取封装配置文件内容5.2 收集系统信息 一. 关联数组定义 从 Bash 4.0 开始,Bash 支持关联数组。关联数组允许你将键和值配对,并通过键来访问值&…...

选择排序
一:基本思想 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。 解释:就是不断的找到最小的放在最左面,然后缩短数组,…...

SQL数据库(MySQL)
一、在Ubuntu系统下安装MySQL数据库 1、更新软件源,在确保ubuntu系统能正常上网的情况下执行以下命令 sudo apt-get update 2、安装MySQL数据库及相关软件包 # 安装过程中设置root用户的密码 123456 sudo apt-get install mysql-server # 安装访问数据库的客…...

在MindSearch中使用SiliconCloud:全面指南**
随着硅基流动(SiliconFlow)提供的InternLM2.5-7B-Chat服务的免费开放,我们迎来了MindSearch部署的全新篇章。这一服务的免费提供,不仅极大地降低了部署门槛,还为MindSearch的使用者带来了纯CPU版本的便利。本文将为您详…...

C++(2)之Linux多线程服务端编程总结
C之Linux多线程服务端编程读书笔记 Author: Once Day Date: 2023年1月31日/2024年8月23日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章可参考专栏: Linux实践…...

【AI视频】复刻抖音爆款AI数字人作品初体验
博客主页: [小ᶻZ࿆] 本文专栏: AI视频 | AI数字人 文章目录 💯前言💯抖音上的爆火AI数字人视频💯注册HeyGen账号💯复刻抖音爆款AI数字人💯最终生成效果💯小结 对比原视频效果:…...
Mysql 面试题总结
1. Mysql 数据库,隔离级别有哪几个? 在 MySQL 数据库中,事务的隔离级别决定了一个事务在执行期间对其他事务可见的数据变化情况。MySQL 支持 SQL 标准定义的四种隔离级别,从低到高依次为: 读未提交(READ U…...

stack - queue
1.容器适配器 (1) 什么是适配器? 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),该种模式是将一个类的接口转换成客户希望的另外一个接口 (2) STL标准库中stack和queue的底层结构 虽然stack和…...

微软九月补丁星期二发现了 79 个漏洞
微软将在2024 年 9 月补丁星期二修复 79 个漏洞。 微软有证据表明,发布的四个漏洞被野外利用和/或公开披露;所有四个漏洞均已在CISA KEV上列出。微软还在修补四个关键的远程代码执行 (RCE) 漏洞。 不同寻常的是,微软本月尚未修补任何浏览器…...

研1日记12
1. 改19->10 2. 学习数据不平衡问题 1. 欠采样 合并两个样本数据 两种方式 1. 按原分布比例划分。sklearn中train_test_split里,参数stratify含义解析_traintestsplit参数stratify-CSDN博客 3.刘二大人 卷积操作 待看论文: 刘老师指导:…...
Rocky Linux 9安装mysqlclient库报错的解决方法
环境 VMware Rocky Linux 9.4 MySQL 8.0 安装mysqlclient报错 yum install python3-devel pip3 install mysqlclient报错: Downloading http://mirrors.aliyun.com/pypi/packages/37/fb/d9a8f763c84f1e789c027af0ffc7dbf94c9a38db961484f253f0552cbb47/mysqlcli…...

Spring Boot母婴商城:安全、便捷、高效
2 相关技术 2.1 SSM框架介绍 本课题程序开发使用到的框架技术,英文名称缩写是SSM,在JavaWeb开发中使用的流行框架有SSH、SSM、SpringMVC等,作为一个课题程序采用SSH框架也可以,SSM框架也可以,SpringMVC也可以。SSH框架…...
php实现kafka
kafka类: <?phpclass b2c_kafka {public $broker_list;public $topic;public $group_id;protected $producer null;protected $consumer null;protected $receive_wait_time;protected $receive_wait_num;/*** 构造方法* param object app*/public function …...

YOLOv10改进系列,YOLOv10损失函数更换为Powerful-IoU(2024年最新IOU),助力高效涨点
改进前训练结果: 改进后的结果: 摘要 边界框回归(BBR)是目标检测中的核心任务之一,BBR损失函数显著影响其性能。然而,观察到现有基于IoU的损失函数存在不合理的惩罚因子,导致回归过程中锚框扩展,并显著减缓收敛速度。为了解决这个问题,深入分析了锚框扩展的原因。针…...
工具知识 | Linux 常用命令参考手册
目录 文件 查看文件内容 headtailcatnlmore 创建 touchmkdirmktemp 删除 rmrmdir 查找文件 findlocate lspwdwcchattrpastestatgrepsedcdcpmvopensourcetreelnfilesortuniqsplitvim 系统管理 nohupwatchpingwhichshutdownrebootuptimecrontabatunameifconfigwhereischmodlsofc…...
mysql 常用知识点总结
MySQL 是一种广泛使用的关系型数据库管理系统(RDBMS),它基于结构化查询语言(SQL)。了解 MySQL 的语法对数据库管理和操作非常重要。以下是 MySQL 语法的详细完整解释,涵盖基本概念、创建表、查询、修改数据…...
conda常用指令
1、查看conda版本 conda --version 2、更新conda conda update conda 3、查看conda环境信息 conda info 4、查看已有虚拟环境 conda info --envs conda info -e conda env list 5、创建新虚拟环境 conda create --name myenv python3.8 6、激活环境和退出环境 conda…...

前后端分离项目--下载功能
文章目录 不使用代理服务器blobblob构造函数通过FormData对象的getBlob方法创建Blob对象将Blob对象转换成UR 使用代理服务器 前后端分离项目中下载与其他接口的使用不同,一般下载不走node,不通过代理服务器,而是直接在前台发送请求࿰…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...