Java微服务内存占用分析

2023-11-02

一、Java 进程中有哪些组件会占用内存?

通过 Native Memory Tracking 可以观察到有以下 JVM 组件。在命令行加上-XX:NativeMemoryTracking=summary,会增加3MB左右内存,损失5%-10%CPU,不宜用于生产环境。

使用 jcmd <pid> VM.native_memory summary scale=MB 可以查看内存分配结果。如果报告"Native memory tracking is not enabled", 是因为该进程起动时命令行没有加上-XX:NativeMemoryTracking=summary参数。

1.1 Java 堆

最显而易见的就是 Java 堆,它是 Java 对象存在的地方。它会占用 -Xmx 参数指定大小的内存。

1.2 线程

线程堆栈也会申请内存。堆栈大小由 -Xss 选项指定,默认每个线程1M,幸运的是情况并非那么糟糕。操作系统会以延迟分配的方式分配内存页面,比如在第一次使用时分配,因此实际使用的内存要低得多,通常每个线程堆栈占用80至200KB。

还有其他 JVM 部件会占用本地内存,但它们在总内存消耗中通常比例不大。

1.3 类加载

类的元数据存储在 Metaspace 堆外区域中,包括方法字节码、符号、常量池、注解等。加载的类越多,使用的元数据就越多。可以通过 -XX:MaxMetaspaceSize(默认无上限)和 -XX:CompressedClassSpaceSize(默认1G)选项控制元数据总大小。

1.4 符号表

JVM 有两个主要的 hashtable:符号表包含名称、签名、标识符等,String 表包含对 interned String 引用。如果 Native Memory Tracking 显示 String 表使用了大量内存,这可能意味着应用程序调用 String.intern 过于频繁。

1.5 垃圾回收器

GC 需要额外的内存进行堆管理,主要用于 GC 自身的结构与算法。这些结构包括 Mark Bitmap、Mark Stack(遍历对象关系图)、Remembered Set(记录 region 之间引用)等等。其中一些可以直接调优,例如 -XX: MarkStackSizeMax 选项,另一些依赖于堆布局。其中 G1 region (-XX:G1HeapRegionSize)占用内存较大,Remembered Set 占用内存较小。

GC 的内存开销因算法而异,其中 -XX:+UseSerialGC 与 -XX:+UseShenandoahGC 的开销最小,而 G1 或 CMS 则会轻松占用大约10%的堆内存。

1.6 代码缓存
代码缓存包含动态生成的代码,JIT 编译生成的方法、解释器以及运行时 stub 代码。代码大小受 -XX:ReservedCodeCacheSize选项限制(默认为240M)。关闭 -XX:-TieredCompilation 可以减少已编译代码的数量,从而减小代码缓存。

1.7 编译器

JIT 编译器本身工作时也需要内存。可以通过关闭 Tiered Compilation 或者 -XX:CICompilerCount 减少编译使用的线程数。


1.8 Direct Buffer

应用程序可以通过 ByteBuffer.allocateDirect 调用直接请求非堆内存。默认的非堆内存大小限制由 -Xmx 选项指定,但也可以使用 -XX:MaxDirectMemorySize 覆盖配置。Direct ByteBuffer 包含在 Native Memory Tracking 输出的 Other 区域,在 JDK 11 之前包含在 Internal 区域。

通过 JMX 可以在 JConsole 或 Java Mission Control 中直接看到 Direct Memory 的使用量:

1.9 Native Library

System.Loadlibrary 加载的 JNI 代码可以不受 JVM 控制分配堆外内存,标准 Java Class Library 也是如此。尤其是未关闭的 Java 资源可能造成本地内存泄漏。典型的例子是 ZipInputStream 和 DirectoryStream。

JVMTI 代理,尤其是 jdwp 调试代理,也会造成内存消耗过多。

二 实例

2.1 一个很简单的Java程序内存占用: 15MB

Class: 5039 KB
Thread: 3042 KB
Code: 2557 KB
JavaHeap: 2048 KB
Symbol: 1742 KB
Internal: 230 KB
NativeMemoryTracking: 42 KB

ArenaChunk: 32 KB
GC: 19 KB
Total: 14751 KB [ Heap= 2048 , Thread= 3042 Class= 6781 , Other: 2880 ]

命令行:java -Xint -XX:+UseSerialGC -XX:NativeMemoryTracking=summary -Xmx1024k -Xss160K cn.PigEater

Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode) java version "1.8.0_181"

SprintBoot Jar包 1.7MB .

 

2.2 一个功能简单的Spring Cloud微服务(使用redis/mybatis)内存占用:162MB

JavaHeap: 64 MB
Class: 62 MB
Symbol: 17 MB
Thread: 11 MB
NativeMemoryTracking: 3 MB
Code: 3 MB
Internal: 2 MB
Total: 162 MB [ Heap= 64 , Thread= 11 Class+Symbol= 79 , Other: 8 ]

命令行:java -XX:+UseSerialGC -XX:NativeMemoryTracking=summary -Xms64M -Xmx64M -Xss256k -XX:MaxMetaspaceSize=128M -XX:MetaspaceSize=64M -Xint -Deureka.client.serviceUrl.defaultZone=http://10.32.0.21:8761/eureka/ -jar target/user-kernel-server-0.0.1-SNAPSHOT.jar

SpringBoot Jar包 59MB

 

运行完10000条请求后内存占用:

Class: 68 MB
JavaHeap: 64 MB
Symbol: 18 MB
Thread: 14 MB
NativeMemoryTracking: 3 MB
Internal: 3 MB
Code: 3 MB
Total: 173 MB [ Heap= 64 , Thread= 14 Class= 86 , Other: 9 ]

 

2.3 功能简单的Spring Cloud微服务,使用Serial垃圾回收,64MB Heap内存,执行10000个请求后:220MB

Class: 75 MB
JavaHeap: 64 MB
Code: 41 MB
Thread: 18 MB
Symbol: 18 MB
NativeMemoryTracking: 3 MB
Internal: 3 MB

Total: 222 MB [ Heap= 64 , Thread= 18 Class= 93 , Other: 47 ]

命令行:java -XX:+UseSerialGC -XX:NativeMemoryTracking=summary -Xms64M -Xmx64M -Xss256k -Deureka.client.serviceUrl.defaultZone=http://10.32.0.21:8761/eureka/ -jar target/user-kernel-server-0.0.1-SNAPSHOT.jar

2.4 功能简单的Spring Cloud微服务,使用Serial垃圾回收,256MB Heap内存,执行10000个请求后:430MB

JavaHeap: 256 MB
Class: 74 MB
Code: 42 MB
Internal: 19 MB
Thread: 18 MB
Symbol: 18 MB
NativeMemoryTracking: 3 MB
GC: 1 MB
Total: 431 MB [ Heap= 256 , Thread= 18 Class= 92 , Other: 65 ]

命令行:java -XX:+UseSerialGC -XX:NativeMemoryTracking=summary -Xms256M -Xmx256M -Xss256k -Deureka.client.serviceUrl.defaultZone=http://10.32.0.21:8761/eureka/ -jar target/user-kernel-server-0.0.1-SNAPSHOT.jar

 

2.5 功能简单的Spring Cloud微服务,使用G1垃圾回收,256MB Heap内存,执行10000个请求后:510MB

JavaHeap: 256 MB
Class: 74 MB
GC: 59 MB
Code: 42 MB
Thread: 38 MB
Internal: 20 MB
Symbol: 18 MB
NativeMemoryTracking: 3 MB
Unknown: 0 MB
Total: 510 MB [ Heap= 256 , Thread= 38 Class= 92 , Other: 124 ]

 

三、微服务内存分配大致公式,以256MB Heap内存,Serial GC计算:

heap + 最大thread_num * 256k + jar_package_size * 3 + GC(Serial 0, CMS/G1 heap * 10%)

如:64MB heap, 60线程, jar包60MB,占用内存大约为 64 + 60 * 256k + 60 * 2 = 199 MB 可以正常动行,一般不会超过260 MB

      512MB heap, 300线程,jar包120MB,占用内丰大约为 512 + 300 * 0.25MB + 120 * 2 = 830MB,一般不会超过950MB

 

使用策略

1.1

Heap

1.2

Thread

1.3

Class

1.4

Symbol

1.5

GC

1.6

Code

1.7

Internal

1.8

Direct Buffer

1.9

Native Library

总计

使用策略

1.1

Heap

1.2

Thread

1.3

Class

1.4

Symbol

1.5

GC

1.6

Code

1.7

Internal

1.8

Direct Buffer

1.9

Native Library

总计

JDK1.8 分配方法

-Xmx256M

默认为机器内存的1/4

最小2MB

-Xss256k

默认为1M

最小160k

参考Jar包大小

加上JVM系统中必须的Jar包。

同1.3。

-XX:+UseSerialGC

-XX:+UseG1GC

动态增长,默认与GC有关,SerialGC接近0。

-Xint

-Xmixed

动态增长,与Jar包大小相关。

动态增长,与Jar包大小相关。 默认没有使用,大小为0。 默认没有使用,大小为0。  
2.1 简单Java程序 2MB 3MB 5MB 1.7MB   2.5MB       15MB
2.2 微服务 64MB 11MB 62MB 17MB   3MB 2MB     162MB
2.3 微服务 64MB 18MB 75MB 18MB   41MB 3MB     222MB
2.4 微服务  256MB 18MB 74MB 18MB   42MB 19MB     431MB
2.5 微服务+G1 256MB 38MB 74MB 18MB 59MB 42MB 20MB     510MB
2.6 微服务+G1 1024MB 77MB 80MB 18MB 81MB 60MB 53MB     1398MB

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java微服务内存占用分析 的相关文章

  • 在 Java 中有效地对图像进行颜色循环

    我正在编写一个曼德尔布罗分形查看器 我想以智能的方式实现颜色循环 给定一个图像 我想修改它的 IndexColorModel 据我所知 没有办法修改 IndexColorModel 也没有办法为图像提供新的 IndexColorModel
  • 在 Spring Boot 中重新加载/刷新缓存

    我正在使用 Spring Boot 对于缓存 我使用 Ehcache 到目前为止一切正常 但现在我必须重新加载 刷新 那么我该如何执行此操作 以便我的应用程序不会出现任何停机时间 我在Spring Ehcache中尝试了很多方法 但它不起作
  • 如何更改 JComboBox 下拉列表的宽度?

    我有一个可编辑的JComboBox其中包含单个字母值的列表 因此 组合框非常小 每个字母都有特殊的含义 对于很少使用的字母 有时用户并不清楚 因此我创建了一个自定义ListCellRenderer显示下拉列表中每个字母的含义 不幸的是 这个
  • TestNG 启动期间发生内部错误

    我创建了一个 TestNG 类 FirstTest java 当我将测试用例作为 TestNG Test 运行时 出现以下错误 期间发生内部错误 启动 FirstTest java lang NullPointerException Ecl
  • Criteria eager fetch-joined 集合以避免 n+1 选择

    假设 Item 和 Bid 是实体 一个 Item 有多个 Bid 它们被映射到休眠在典型的父子关系中
  • SimpleDateFormat 无法正确处理 DD

    我正在尝试获得这样的格式 2013 06 15 17 45 我在代码中执行以下操作 Date d new Date SimpleDateFormat ft new SimpleDateFormat YYYY MM DD HH mm Stri
  • BigDecimal 中 Divide 方法的 Scale()

    new BigDecimal 37146555 53880000 divide new BigDecimal 1000000 scale 这返回10 但根据API divide method 返回一个 BigDecimal 其值为 这个 除
  • 在Tomcat中设置环境变量TESSDATA_PREFIX

    我们正在使用名为 Tess4J 的 Tesseract OCR Java 库 如果作为独立应用程序运行 它可以正常工作 它需要一个名为 TESSDATA PREFIX 的变量 其中包含 tessdata 配置和其他字符集相关文件 它也可以与
  • 当用户使用相同的凭据登录两次时如何使用户会话无效

    我正在使用带有 Richfaces 和 Facelets 的 JSF 1 2 我有一个应用程序 其中包含许多会话范围的 Bean 和一些应用程序 Bean 假设用户使用 Firefox 登录 创建一个会话 ID A 然后他打开 Chrome
  • Android 上的自定义视图和窗口属性

    我想要做的是在我的应用程序顶部添加一个视图 该视图类似于过滤器视图 我想操纵屏幕的颜色 并且我还希望能够同时更改屏幕的亮度时间 这两件事似乎是分开起作用的 但不能一起起作用 这是我的代码 添加视图 colourView new Layer
  • EasyMock : java.lang.IllegalStateException: 1 个匹配器预期,2 个记录

    我在使用 EasyMock 2 5 2 和 JUnit 4 8 2 通过 Eclipse 运行 时遇到问题 我已阅读此处所有类似的帖子 但尚未找到答案 我有一个包含两个测试的类 它们测试相同的方法 我正在使用匹配器 每个测试单独运行时都会通
  • Java Timer 类:如果其中一个任务抛出异常,则计时器任务停止执行

    new Timer scheduleAtFixedRate new TimerTask Override public void run System out println run throw new SomeRandomExceptio
  • 无法从 ViewPager 中的 Fragment 编辑 ActionBar 标题

    我有一个Activity它通过一个托管多个片段ViewPager 在活动的onCreate方法我使用以下代码来更改ActionBar title Toolbar toolbar findViewById R id toolbar setSu
  • Android 以编程方式停止 toast 通知?

    有没有办法以编程方式停止 Toast 消息 假设我有一个按钮 单击它可以滚动 toast 消息 并且在 onclick 事件中我想停止队列中的所有消息并只显示新消息 我该怎么做 我的代码的简化版本如下 代码 public class Hel
  • 飞碟 - html 实体未呈现

    我正在使用 Flying saucer lib 生成 pdf 但我对一些 html 实体有问题 我已经在寻找解决方案 我在这个论坛和其他地方找到了很多提示 但仍然存在问题 我尝试过这种方法 http sdtidbits blogspot c
  • System.out.println("嗨"+6+10);打印Hi610?

    为什么要这样做 太令人困惑了 运算符优先级和结合性 两点 操作员 如果一个或两个参数都是字符串 则进行字符串连接 操作员 从左到右工作 所以在你的例子中 Hi 6 is Hi6 and Hi6 10 is Hi610 编辑 正如您在对另一个
  • SecurityContextHolder.getContext().getAuthentication() 返回 null

    我想使用以下代码手动绕过 spring Security 的用户 User localeUser new User UsernamePasswordAuthenticationToken auth new UsernamePasswordA
  • 使用 OpenNLP 获取句子的解析树。陷入困境。

    OpenNLP 是一个关于自然语言处理的 Apache 项目 NLP 程序的目标之一是解析一个句子 并给出其语法结构的树 例如 天空是蓝色的 这句话 可能会被解析为 S NP VP The sky is blue where S是句子 NP
  • JSF - 实施受限页面过滤器

    我正在关注 BalusC 的回答JSF 2 0 如何获取在浏览器地址栏中输入的 URL https stackoverflow com questions 4105263 jsf 2 0 how to get the url that is
  • Java:如何检测(并更改?)System.console 的编码?

    我有一个在控制台上运行的程序 其变音符号和其他特殊字符在 Mac 上以 的形式输出 这是一个简单的测试程序 public static void main String args System out println h h System

随机推荐

  • 七牛产品概览

    七牛云产品概览 服务对象 个人开发者 创业团队 企业用户 对象存储 Kodo 简介 七牛云提供的数据存储服务主要是针对静态资源文件 image js css 音频 视频 文档 PDF txt json xml yml apk 等等 提供存储
  • Java中string的null和“”对比

    Java中字符串的比对用string equals object 来做 但与空字符串比对的时候要注意 如果是 话 用string equals 如果是null的时候 string equals null 会报错 应该使用string nul
  • SYSAUX表空间清理之WRH$_ACTIVE_SESSION_HISTORY

    查看sysaux表空间使用率高 对于sysaux表空间之前有文章讨论过 本次直入正题 1 检查sysaux表空间占用空间较大的segments SQL gt select from select owner segment name seg
  • mysql while bug_案例分享:MySQL BUG处理

    近一个月处理历史数据问题时 居然连续遇到了2个MySQL BUG 分享给大家一下 也欢迎指正是否有问题 BUG1 数据库版本 MySQL5 7 25 28 操作系统 Centos 7 7 不重要 数据库架构 主 从 级联从 数据库参数 in
  • Java 冒泡排序示例

    以下是 Java 语言实现冒泡排序的示例代码 public class BubbleSort public static void main String args int arr 5 2 8 3 9 1 bubbleSort arr Sy
  • 64、3D Neural Scene Representations for Visuomotor Control

    简介 主页 https 3d representation learning github io nerf dy 机器人操作模型学习的核心问题之一是如何确定 dynamics model 的状态表示 理想的表示应该易于捕捉环境动态 展示对场
  • CDN是做什么用的,怎么一直有人在推荐使用?

    CDN 内容分发网络 的作用与不断的推荐使用背后有着深刻的原因 这是因为CDN在互联网领域发挥着重要且多方面的作用 为许多网站和在线业务提供了显著的优势 首先 让我们来了解CDN的作用是什么 CDN是一种网络架构 旨在将网站的静态资源 如图
  • 100级小号搬砖地图_DNF100版本搬砖地图最高收益攻略(利润化透明)

    DNF搬砖那个地图收益最高 100版本搬砖攻略 大家都知道DNF是一款经典的手游 到现在已经运营十年了 同时也是一款氪金的 当然对于神豪来说都是小问题 但是对于一般的玩家 想玩DNF建议还是先去医院检查一下肝 肝不好建议别入坑 今天小编就给
  • 数学的科普文

    20210105 这次又是整理自己的书签 然后发现了这个文章 这个文章应该是很久之前的时候我看到的 觉得很有趣 应该是当时学习最小二乘法的时候看到的 所以这篇文章就来记录一些平时看到的不错的科普文 以前很多文章都错过了 挺可惜的 正态分布的
  • React Hook的useCallback,memo,usememo的使用

    1 useCallback 每当组件重新渲染的时候 我们之前定义的函数就会被重新声明一次 即使这个函数不需要做出改变 这时可以使用useCallback useCallback主要用于缓存一个函数 useCallback接收两个参数 第一个
  • Apriori算法完整代码

    文章目录 apriori py apriori py usr bin env python coding utf 8 from numpy import 加载数据集 def loadDataSet return 1 3 4 2 3 5 1
  • 深度学习与计算机视觉系列(5)_反向传播与它的直观理解

    作者 寒小阳 龙心尘 时间 2015年12月 出处 http blog csdn net han xiaoyang article details 50321873 声明 版权所有 转载请联系作者并注明出处 1 引言 其实一开始要讲这部分内
  • javaScript:宏任务与微任务的运行顺序

    在写代码的时候 我使用Element组件中的表单重置方法 和vue中子传父方法 这里我想要通过 async 和 await 的特点 await 下一行代码作为微任务执行 来规定代码的执行顺序 让重置方法 滞后 于数据传递 执行 确定按钮 子
  • Java底层原理——HashMap面试问题

    什么时候会用到HashMap 他有什么特点 是基于Map接口实现的 存储键值对时 可以接收null的键值 是非同步的 HashMap存储着Entry hash key value next 对象 你知道HashMap的工作原理吗 通过has
  • Linux驱动

    一 前言 设备树是每一个Linux驱动工程师都必须掌握的一个知识点 有很多之前做单片机的朋友刚接触Linux驱动时 会一脸懵 其实设备树的使用并没有大家想像的那么复杂 对于大部分工程师来说 只要会修改即可 很多粉丝留言说 希望彭老师提供一个
  • 记录CTF命令执行练习中遇到的几道题(一些PHP命令过滤的绕过方法)

    题目1 if isset GET Command GET Command command GET Command if preg match f a g flag cat tac more ls system exec popen pass
  • 在SQL中寻找唯一记录的3种终极方法

    在SQL中寻找唯一记录的3种终极方法 停止使用DISTINCT 开始使用这些快速替代方法 以避免混淆 照片 Luis Cortes on Unsplash 不使用DISTINCT关键字就能获得唯一记录 在你的数据分析项目中 只要你需要从数据
  • Windows server 2008 R2远程桌面3389端口号修改及远程桌面窗口大小调整

    转自 https help aliyun com document detail 51644 html spm 5176 doc51644 6 784 4iAHWH 修改 Windows 服务器默认远程端口 操作步骤 远程连接并登录到 Wi
  • ConcurrentHashMap概述

    1 前言 为什么要使用 ConcurrentHashMap 主要基于两个原因 在并发编程中 jdk1 7的情况下使用 HashMap 可能造成死循环 而jdk1 8 中有可能会造成数据丢失 HashTable 效率非常低下 2 Concur
  • Java微服务内存占用分析

    一 Java 进程中有哪些组件会占用内存 通过 Native Memory Tracking 可以观察到有以下 JVM 组件 在命令行加上 XX NativeMemoryTracking summary 会增加3MB左右内存 损失5 10