java服务内存说明及配置详解

news2024/12/23 7:01:13

java进程内存

JVM内存分布图:
java mem

【java进程内存】=【堆外内存】 + 【jvm堆内存】
【堆外内存】= 【Metaspace】+ 【Direct Memory】+【JNI Memory】+【code_cache】+ …
堆外内存泄漏的排查在于【本地内存(Native Memory)】=【Direct Memory】+【JNI Memory】

一般堆内存比较好理解,而对于堆外内存,了解比较少。

什么是堆外内存

Non-Heap Space 翻译为非堆内存,也被称为Off-Heap(堆外内存),大家习惯于叫这部分内存为堆外内存。查看了很多国内外文章,对于这块内存,没有很统一的定义。
较可信的是分为下面两种定义:

  1. 广义上的Non-Heap
    除开Heap以外的所有内存,包括MetaSpace、NativeMemory(JNI Memory、Direct Memory等)、Stack、Code Cache等。
    下面讲解的Non-Heap是针对于广义的定义。
  2. 狭义上的Non-Heap
    只包含Metaspace、code_cache。

注意:
监控系统里会有Non-Heap的监控,例如SkyWalking、Arthas的Non-Heap指标,都是通过JDK自带的MemoryMXBean方法获取的。
所以一般监控系统采集的Non-Heap只是Heap以外的一部分内存!还需要留意NativeMemory等等内存。
对应的代码:

@Override
public long getNonHeapMemoryMax() {
  return memoryMXBean.getNonHeapMemoryUsage().getMax();
}

@Override
public long getNonHeapMemoryUsed() {
  return memoryMXBean.getNonHeapMemoryUsage().getUsed();
}

JNI Memory内存

JNI (Java Native Interface) memory是指Java应用程序与本地代码交互时使用的内存。Java Native Interface (JNI) 是 Java 与本地(如 C 或 C++)代码进行交互的桥梁。出了问题所以需要使用C、C++的思路去解决。
在这里插入图片描述

在这里插入图片描述

ptmalloc2在高并发分配内存时,会存在较多内存碎片无法释放的情况,碎片积压到一定程度甚至会导致进程内存不够用,最终堆外内存泄漏。因此MySQL、TFS、Tair、Redis这些中间件部署时,指定jemlloc内存分配器替代ptmalloc2可更好地管理内存。

内存排查工具

java内存查看相关工具

在这里插入图片描述

实例:

  1. 确定到底是哪个进程占用内存高

ps aux --sort=-%mem

  1. 通过pmap命令可以看到最真实的JVM heap的物理内存的占有量

pmap -X 27045 | head -2; pmap -X 27045 | awk ‘NR>2’ | sort -nr -k6 | head -10

堆外内存相关工具

不同的内存区域可以使用不同的命令进行排查,同时也留意合理设置对应内存区域的参数。
在这里插入图片描述

JVM内存使用量过大问题排查思路

在这里插入图片描述
参考: 【JVM内存】系统性排查JVM内存问题的思路

JVM参数设置说明

  • -Xms4g

初始堆大小 默认物理内存的1/64(<1GB) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制。初始和最大最好设置成一样,避免堆内存在应用运行过程中自动扩容而影响服务稳定性

  • -Xmx4g

最大堆大小 默认物理内存的1/4(<1GB) 默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。初始和最大最好设置成一样,避免堆内存在应用运行过程中自动扩容而影响服务稳定性
另外一般的应用,XMX可以设置为物理内存的1/2到2/3,较充分地去利用内存。
需要较多地使用Heap外内存应用,物理内存不要超过1/2,例如ElasticSearch、RocketMQ-broker、Kafka等中间件,需要大量读写文件,操作系统需要大量的Page Cache,才能有足够的缓存提高性能,所以JVM Heap不要过大,以预留给非Heap的其他内存。

  • -Xmn

年轻代大小(1.4or lator) 整个堆大小=年轻代大小 + 年老代大小 + 持久代大小. 增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。尽量设置小一点

  • -Xss128k

每个线程的堆栈大小 JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
一般小的应用, 如果栈不是很深, 应该是128k够用的 大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。

  • -XX:SurvivorRatio=8

Eden区与Survivor区的大小比值 Eden区与Survivor区的大小比值 设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10

  • -XX:AlwaysPreTouch

(1) 如果未配置了-XX:AlwaysPreTouch,则实际是使用的是虚拟内存,给了一张空头支票,只在首次访问时,例如存放一批新的Java对象数据,但原来申请的内存不够用了,需要新的内存来,这时才需要分配物理内存,也就是通过缺页异常进入内核中,再由内核来分配内存,再交给JVM进程使用。一般情况,不会配置-XX:AlwaysPreTouch。
(2) 如果配置了-XX:AlwaysPreTouch,则JVM启动时,则不仅分配Xms的大小的虚拟内存,还会使用物理内存、填充整个堆。
提前申请好物理内存,减少程序运行过程中发生的物理内存分配带来的延迟,可以提升性能。例如部署elasticsearch节点时,可以指定该参数,提升性能。

  • -XX:+UseG1GC

选择使用G1垃圾收集器,G1日志解析参考:G1日志解析

  • -XX:MetaspaceSize=128M

元数据空间的扩容临界值,元数据空间的内存commited指超过256M,将会发生mixed GC和扩容

  • -XX:MaxMetaspaceSize=256M

一般大小256M足够,因为默认值无限大,如果出现频繁加载class等情况,容易打满系统内存。报错:java.lang.OutOfMemoryError: Metaspace。

  • -XX:MaxDirectMemorySize=1G

默认值等于-Xmx,这个参数直接干预sun.nio.MaxDirectMemorySize这个属性,会限制nio可用的最大直接内存为1G,最好配置直接内存,因为堆外内存一旦泄漏可能会打满整个系统内存,并且很难排查。Netty等框架会用到DirectMemory,且一般设置1G足够。报错:java.lang.OutOfMemoryError: Direct buffer memory。

  • -XX:InitialBootClassLoaderMetaspaceSize=256M

给每个classloader分配的元数据空间初始值是256M

  • -XX:+PrintGCDetails

打印GC日志

  • -XX:+PrintGCDateStamps

打印GC日志附带时间戳

  • -XX:+PrintHeapAtGC

GC之前和GC之后的堆的内存使用情况要打印出来

  • -Xloggc:/data/logs/java/gc.log

GC日志的存储路径(前缀)

  • -XX:+UseGCLogFileRotation

GC日志文件开启滚动存储
-XX:NumberOfGCLogFiles=5
GC日志文件最多保留5个

  • -XX:GCLogFileSize=30M

每个GC日志文件最大30M,超过30M,生成新的文件

  • -XX:+HeapDumpOnOutOfMemoryError

当发生内存溢出时dump堆转储文件

  • -XX:HeapDumpPath=/data/logs/java/heap_dump_%p.hprof

堆转储文件的存放地址

JVM方法区(元空间)大小设置

-XX:MetaspaceSize

设置元空间初始大小
-XX:MaxMetaspaceSize

最大可分配大小
解释

JDK8及以后:可以使用-XX:MetaspaceSize和-XX:MaxMetaspaceSize设置元空间初始大小以及最大可分配大小。
例子:设置初始大小是100M,最大可分配空间也是100M。-XX:MetaspaceSize=100m -XX:MaxMetaspaceSize=100m。
如果不指定元空间的大小,默认情况下,元空间最大的大小是系统内存的大小,元空间一直扩大,虚拟机可能会消耗完所有的可用系统内存。如果元空间内存不够用,就会报OOM。默认情况下,对应一个64位的服务端JVM来说,其默认的-XX:MetaspaceSize值为21MB,这就是初始的高水位线,一旦元空间的大小触及这个高水位线,就会触发Full GC并会卸载没有用的类,然后高水位线的值将会被重置。如果初始化的高水位线设置过低,会频繁的触发Full GC,高水位线会被多次调整。所以为了避免频繁GC以及调整高水位线,建议将-XX:MetaspaceSize设置为较高的值, -XX:MaxMetaspaceSize,一般大小256M足够,因为默认值无限大,如果出现频繁加载class等情况,容易打满系统内存,出现系统风险。

Heap Dump文件生成

heap dump进行分析工具

事先需要准备软下软件包:

  • JDK 11+(目前MAT最新版本1.13.0要求使用)
  • Memory Analyzer Tool (MAT)

MAT官方下载页面:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

软件包准备就绪后,解压JDK和MAT到任意目录,无需其他安装操作。

使用命令可以立刻获取某个Java进程的heap dump。

使用jmap命令:

jmap -dump:live,format=b,file=/path/to/heapdump.hprof [pid]

使用jcmd命令:

jcmd [pid] GC.heap_dump /path/to/heapdump.hprof

其中为需要分析的Java进程的pid。/path/to/heapdump.hprof为生成的heap dump文件所在的路径。

在特定时间点生成

考虑到如下场景:我们需要获取Java程序出现异常的时候(例如OOM)的heap dump。这种场景下我们无法使用上面讲解的命令,Java进程出现问题的时候可能已经被系统kill掉。因此我们需要配置JVM,让他能够在特定时间点自动生成heap dump。

下面列出生成heap dump的时间点和对应的JVM参数。

在OOM的时候生成heap dump:

-XX:+HeapDumpOnOutOfMemoryError

在full GC前生成heap dump:

-XX:+HeapDumpBeforeFullGC

在full GC后生成heap dump:

-XX:+HeapDumpAfterFullGC

在按下ctrl+break的时候生成heap dump:

-XX:+HeapDumpOnCtrlBreak

注意: 指定heap dump文件生成的路径需要配置-XX:HeapDumpPath=/path/to/heapdump.hprof。

Heap Dump分析

对于不是很大的heap dump文件(不大于MAT分析机器内存的1.2倍),我们可以将heap dump文件压缩后下载到本地,使用MAT图形界面方式分析。操作方法比较直观(File -> Open Heap Dump…),这里不再赘述。

生产环境中可能遇到特别大的heap dump。比如我们要分析一个30G的heap dump。将其在服务器上压缩之后,空间占用仍有大约10G,下载到本地耗时很长。本地开发机器一般也很少见32G内存机器,分析的时候会出现内存溢出问题。这种情况下我们需要使用MAT提供的命令行功能,在服务器上进行分析并输出分析报告。这些分析报告是静态的web页面,只有几百KB大小。需要在本地做的仅仅是将这些报告下载下来用浏览器打开,这样完美避免了本地开发环境配置不足的问题。

在服务器上使用MAT命令行分析的方法很简单。在MAT安装目录中执行:

./ParseHeapDump.sh xxx.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components

其中xxx.hprof在实际使用的时候需要替换为hprof文件的路径。运行完毕后在hprof文件所在目录会生成一系列的index/threads文件和3个压缩文件。这3个压缩文件是我们重点关注的分析报告,分别为:

  • xxx_Leak_Suspects.zip:报告包含怀疑造成内存泄漏的地方,报告中包含了class层级图。对于OOM的场景能够很容易的定位到是哪个对象占用了大量内存不释放。
  • xxx_System_Overview.zip:包含heap dump基本信息,dump进程JVM的相关配置和线程信息等。
  • xxx_Top_Components.zip:查看占用空间最大的几个object/class/classloader/package等。报告以饼图和表格的形式展示。通过这个报告可以定位出Java程序运行时哪些对象占用内存较多,对问题排查和程序优化很有帮助。

这三个报告是分析问题的关键。我们通过报告找出内存占用过大的对象,然后结合日志和项目源代码分析程序逻辑,逐步定位出问题。

jvm配置实例

  1. demo1
export JAVA_OPTS="-Xmx2048m -Xms2048m -Xss128k -XX:SurvivorRatio=8 -XX:MetaspaceSize=256m \
-XX:MaxDirectMemorySize=1G \
-XX:+UseG1GC -XX:MaxGCPauseMillis=300 \
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/data/heapdump.hprof \
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC \
-Xloggc:/export/Data/gc-%t.log -XX:+UseGCLogFileRotation -XX:GCLogFileSize=100M -XX:NumberOfGCLogFiles=20"

echo "环境变量:"
echo "JAVA_OPTS:$JAVA_OPTS"
echo "JAVA_OPTS_EXT:$JAVA_OPTS_EXT"

echo "应用启动命令:"
echo "java   $JAVA_OPTS $JAVA_OPTS_EXT -jar $MAIN_JAR >/dev/null 2>&1"

java ${PFINDER_AGENT:-}  $JAVA_OPTS $JAVA_OPTS_EXT -jar $MAIN_JAR >/dev/null 2>&1

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

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

相关文章

Android---打开相机拍照

简单实现打开系统系统相机拍一张图片并显示在UI上&#xff0c;适用与个人主页头像的切换。 1. 添加权限。AndroidManifest.xml里添加使用相机的权限。 <uses-permission android:name"android.permission.CAMERA"/> 2. 布局。布局内容比较交单&#xff0c;一…

Ubuntu上安装、使用Redis的详细教程

这篇文章简单地介绍一下怎么在linux虚拟机上完成redis的安装及使用。 目录 1、安装redis 2、使用redis 3、启动/关闭redis 启动redis 启动方式一 启动方式二 启动方式三 重启redis 关闭redis 查看redis状态 4、在宿主机连接redis 5、通过java连接redis 创建maven项…

Webpack监视文件修改,自动重新打包文件

方法一&#xff1a;使用watch监视文件变化 在终端中输入以下指令&#xff1a; npx webpack --watch 我们使用这种方法监听文件变化时只会监听我们计算机本地的文件变化&#xff0c;在开发场景中我们的项目是要部署到服务器中的&#xff0c;因此这种方式并不推荐。 方法二&…

proteus中的各种电阻-可变电阻-排阻

在原理图中使用各类型的电阻是很常见的事情&#xff0c;尤其类似与排阻、可变电阻&#xff0c;但这些电阻对于不熟悉proteus的童鞋来说&#xff0c;一下子可能很难找到&#xff0c;或者很难找心中所想的那个类型&#xff0c;这里分类列出&#xff0c;便于大家使用。 文章目录 一…

Kubernetes集群+Keepalived+Nginx+防火墙实例

文章目录 实验前期规划1.拓扑图结构2.实验要求3.实验环境规划 一.kubeadm 部署 K8S 集群架构1.环境准备2.三个节点安装docker3.三个节点安装kubeadm&#xff0c;kubelet和kubectl4.部署K8S集群&#xff08;1&#xff09;初始化&#xff08;2&#xff09;部署网络插件flannel&am…

腾讯云COS+Picgo+Typora图床搭建

文章目录 什么是图床&#xff1f;配置腾讯云COS整体流程注册腾讯云账号并开通配置COS下载并配置PicGoTypora配置PicGo 可视化管理工具 什么是图床&#xff1f; 百度百科是这样解释的&#xff1a; 图床一般是指储存图片的服务器&#xff0c;有国内和国外之分。国外的图床由于有…

2023-9-22 整数划分

题目链接&#xff1a;整数划分 转化成背包问题 #include <iostream> #include <algorithm>using namespace std;const int N 1010, mod 1e9 7;int n; int f[N];int main() {cin >> n;f[0] 1;// i 相当于第i个物品的体积for(int i 1; i < n; i )// j …

计算机视觉: 三维物体生成

三维物体生成与编辑 论文地址: Controllable Mesh Generation Through Sparse Latent Point Diffusion Models 背景 数据是目前数字化和AI领域最宝贵的财富之一&#xff0c;但是对于目前的开发者来说&#xff0c;收集数据都意味着极大的成本。所以建立一个高效的生成模型能极…

Fair原理篇之Fair逻辑动态化通信实现

Fair 逻辑动态化,是对一期布局动态化的增强。为了实现逻辑动态化,我们当时考虑了多种方案,方案主要集中在这三个方面,一种是对google提供的JIT进行裁切,第二种是自定义解析引擎,第三种借助js的能力。 下面主要讲一下几方面: 架构的标准化通信协议的实现js文件的加载与释…

MongoDB 是什么和使用场景概述(技术选型)

一、从NOSQL(Not Only SQL)说起 常见的数据库可以分为下面的两种类型&#xff1a; RDBMS&#xff08;关系型数据库&#xff09;&#xff1a;常见的关系型数据库有 Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL&#xff1b;NoSQL&#xff08;非关系型数据库&a…

计算机视觉与深度学习-循环神经网络与注意力机制-RNN(Recurrent Neural Network)、LSTM-【北邮鲁鹏】

目录 举例应用槽填充&#xff08;Slot Filling&#xff09;解决思路方案使用前馈神经网络输入1-of-N encoding(One-hot)&#xff08;独热编码&#xff09; 输出 问题 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;定义如何工作深度Elman Netwo…

DAB-DETR

DAB-DETR&#xff08;2022ICLR&#xff09; DAB&#xff1a;Dynamic Anchor Boxes 贡献&#xff1a; 明确了不是由于learnable queries导致的收敛缓慢 4D anchor Anchor Update Width & Height Modulated Temperature Tuning 前半部分&#xff1a;Why a positional …

每日一题~将有序数组转换为二叉搜索树

原题链接&#xff1a;108. 将有序数组转换为二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 思路分析&#xff1a; 今天这道题比较简单&#xff0c;我们看一下数组和树之间的联系很容易就能发现规律。 通过简单观察我们发现&#xff0c;位于数组中…

CSDN博客去水印方法

直接在 创作中心->博客 设置这里关了好像就行了&#xff0c;之前方法是找图片链接?后面的一大串字符给去掉。

Java由浅入深理解线程池设计和原理

目录 1 线程1.1 什么是线程&#xff1f;什么是进程&#xff1f;1.2 java中线程的实现方式有几种?1.3 线程的生命周期是什么&#xff1f; 2 线程存在的问题2.1 一个线程只能执行一个任务2.2 线程执行完后销毁,无法复用2.3 线程过多,导致JVM宕机 3 初识线程池3.1 了解J.U.C3.2 线…

计网第五章(运输层)(六)(TCP可靠传输的实现)

目录 一、基本概述 二、具体实现 1.前后沿&#xff1a; 2.利用指针描述发送窗口的状态 3.有差错情况 之前在数据链路层时已经讨论过可靠传输&#xff08;计网第三章&#xff08;数据链路层&#xff09;&#xff08;二&#xff09;&#xff08;可靠传输&#xff09;&#x…

电表智能管理系统-实现智能化、数字化的电力管理

随着信息技术的发展&#xff0c;智能电表已经成为了现代电力管理的重要组成部分。智能电表能够实时监测和记录用电量&#xff0c;自动控制用电&#xff0c;从而实现更加智能、高效的电力管理。 智能电表是一种能够自动监测和记录用电量&#xff0c;并能够自动控制用电的设备…

IDEA中取消双击shift全局搜索

设置如图步骤&#xff1a; 取消双击shift之后&#xff0c;如果想再次使用全局搜索&#xff0c;可以通过&#xff1a; ctrlshifA

Vue与relation-graph:高效打造关系图的秘诀

产品提需求啦&#xff0c;有一个需求就是实现一个功能&#xff1a;展现各个文件之间的调用关系&#xff0c;通过关系图的形式进行展示出来。 之前考虑使用antv x6实现此功能&#xff0c;但是考虑到只是展示的功能&#xff0c;也不需要进行交互&#xff0c;所以放弃使用antv x6&…

【操作系统笔记十二】Linux常用基础命令

Linux 常用快捷键 Tab 命令或路径等的补全键&#xff0c;特别常用的快捷键Ctrl insert 复制命令行内容&#xff08;常用可提高效率&#xff09;Shift insert 粘贴命令行内容&#xff08;常用可提高效率&#xff09;Ctrl C 中断当前任务&#xff08;退出&#xff09;Ctrl Z…