面试官: 你们生产环境的JVM怎么设置的?

2023-05-16

前言

这篇文章,给大家聊一个生产环境的实践经验:线上系统部署的时候,JVM堆内存大小是越大越好吗

先说明白一个前提,本文主要讨论的是Kafka和Elasticsearch两种分布式系统的线上部署情况,不是普通的Java应用系统。


1、是否依赖Java系统自身内存处理数据?

先说明一点,不管是我们自己开发的Java应用系统,还是一些中间件系统,在实现的时候都需要选择是否基于自己Java进程的内存来处理数据。

大家应该都知道,Java、Scala等编程语言底层依赖的都是JVM,那么只要是使用JVM,就可以考虑在JVM进程的内存中来放置大量的数据。

还是给大家举个例子,大家应该还记得之前聊过消息中间件系统。

比如说系统A可以给系统B发送一条消息,那么中间需要依赖一个消息中间件,系统A要先把消息发送到消息中间件,然后系统B从这个消息中间件消费到这条消息。

大家看下面的示意图。

在这里插入图片描述

大家应该都知道,一条消息发送到消息中间件之后,有一种处理方式,就是把这条数据先缓冲在自己的JVM内存里。

然后过一段时间之后,再从自己的内存刷新到磁盘上去,这样可以持久化保存这条消息,如下图。

在这里插入图片描述

2、依赖Java系统自身内存有什么缺陷

如果用类似上述的方式,依赖Java系统自身内存处理数据,比如说设计一个内存缓冲区,来缓冲住高并发写入的大量消息,那么是有其缺陷的。

最大的缺陷,其实就是JVM的GC问题,这个GC就是垃圾回收,这里简单说一下他是怎么回事。

大家可以想一下,如果一个Java进程里老是塞入很多的数据,这些数据都是用来缓冲在内存里的,但是过一会儿这些数据都会写入磁盘。


那么写入磁盘之后,这些数据还需要继续放在内存里吗?

明显是不需要的了,此时就会依托JVM垃圾回收机制,把内存里那些不需要的数据给回收掉,释放掉那些内存空间腾出来。

但是JVM垃圾回收的时候,有一种情况叫做stop the world,就是他会停止你的工作线程,就专门让他进行垃圾回收。

这个时候,他在垃圾回收的时候,有可能你的这个中间件系统就运行不了了。

比如你发送请求给他,他可能都没法响应给你,因为他的接收请求的工作线程都停了,现在人家后台的垃圾回收线程正在回收垃圾对象。

大家看下图。

在这里插入图片描述

虽然说现在JVM的垃圾回收器一直在不断的演进和发展,从CMS到G1,尽可能的在降低垃圾回收的时候的影响,减少工作线程的停顿。

但是你要是完全依赖JVM内存来管理大量的数据,那在垃圾回收的时候,或多或少总是有影响的。

所以特别是对于一些大数据系统,中间件系统,这个JVM的GC(Garbage Collector,垃圾回收)问题,真是最头疼的一个问题。


3、优化为依赖OS Cache而不是JVM

所以类似Kafka、Elasticsearch等分布式中间件系统,虽然也是基于JVM运行的,但是他们都选择了依赖OS Cache来管理大量的数据。

也就是说,是操作系统管理的内存缓冲,而不是依赖JVM自身内存来管理大量的数据。

具体来说,比如说Kafka吧,如果你写一条数据到Kafka,他实际上会直接写入磁盘文件。

但是磁盘文件在写入之前其实会进入os cache,也就是操作系统管理的内存空间,然后过一段时间,操作系统自己会选择把他的os cache的数据刷入磁盘。


然后后续在消费数据的时候,其实也会优先从os cache(内存缓冲)里来读取数据。

相当于写数据和读数据都是依托于os cache来进行的,完全依托操作系统级别的内存区域来进行,读写性能都很高。

此外,还有另外一个好处,就是不要依托自身JVM来缓冲大量的数据,这样可以避免复杂而且耗时的JVM垃圾回收操作。

大家看下面的图,其实就是一个典型的Kafka的运行流程。

在这里插入图片描述

然后比如Elasticsearch,他作为一个现在最流行的分布式搜索系统,也是采用类类似的机制。

大量的依赖os cache来缓冲大量的数据,然后在进行搜索和查询的时候,也可以优先从os cache(内存区域)中读取数据,这样就可以保证非常高的读写性能。


4、老司机经验之谈:

依赖os cache的系统JVM内存越大越好?

所以现在就可以进入我们的主题了,那么比如就以上述说的kafka、elasticsearch等系统而言,在线上生产环境部署的时候,你知道他们是大量依赖于os cache来缓冲大量数据的。

那么,给他们分配JVM堆内存大小的时候是越大越好吗?

明显不是的,假如说你有一台机器,有32GB的内存,现在你如果在搞不清楚状况的情况下,要是傻傻的认为还是给JVM分配越大内存越好,此时比如给了16G的堆内存空间给JVM,那么os cache剩下的内存,可能就不到10GB了,因为本身其他的程序还要占用几个GB的内存。


那如果是这样的话,就会导致你在写入磁盘的时候,os cache能容纳的数据量很有限。

比如说一共有20G的数据要写入磁盘,现在就只有10GB的数据可以放在os cache里,然后另外10GB的数据就只能放在磁盘上。

此时在读取数据的时候,那么起码有一半的读取请求,必须从磁盘上去读了,没法从os cache里读,谁让你os cache里就只能放的下10G的一半大小的数据啊,另外一半都在磁盘里,这也是没办法的,如下图。

在这里插入图片描述

那此时你有一半的请求都是从磁盘上在读取数据,必然会导致性能很差。

所以很多人在用Elasticsearch的时候就是这样的一个问题,老是觉得ES读取速度慢,几个亿的数据写入ES,读取的时候要好几秒。

那能不花费好几秒吗?你要是ES集群部署的时候,给JVM内存过大,给os cache留了几个GB的内存,导致几亿条数据大部分都在磁盘上,不在os cache里,最后读取的时候大量读磁盘,耗费个几秒钟是很正常的。


5、正确的做法:

针对场景合理给os cache更大内存

所以说,针对类似Kafka、Elasticsearch这种生产系统部署的时候,应该要给JVM比如6GB或者几个GB的内存就可以了。

因为他们可能不需要耗费过大的内存空间,不依赖JVM内存管理数据,当然具体是设置多少,需要你精准的压测和优化。

但是对于这类系统,应该给os cache留出来足够的内存空间,比如32GB内存的机器,完全可以给os cache留出来20多G的内存空间,那么此时假设你这台机器总共就写入了20GB的数据,就可以全部驻留在os cache里了。

然后后续在查询数据的时候,不就可以全部从os cache里读取数据了,完全依托内存来走,那你的性能必然是毫秒级的,不可能出现几秒钟才完成一个查询的情况。

整个过程,如下图所示:

在这里插入图片描述

所以说,建议大家在线上生产系统引入任何技术的时候,都应该先对这个技术的原理,甚至源码进行深入的理解,知道他具体的工作流程是什么,然后针对性的合理设计生产环境的部署方案,保证最佳的生产性能。

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

面试官: 你们生产环境的JVM怎么设置的? 的相关文章

  • 为什么通用列表的声明存在差异?

    我想声明两个列表 首先是一个整数列表 我将其声明为 List
  • 运行JDK代码时Java JIT会作弊吗?

    我正在对一些代码进行基准测试 但我无法让它运行得像java math BigInteger https docs oracle com javase 7 docs api java math BigInteger html 即使使用完全相同
  • 有什么方法可以显示正在运行的 JVM 中使用的标志吗?

    尽管我们已经为应用程序显式设置了许多 JVM 标志 但很难知道是否 1 布尔标志默认已打开 默认值在 JDK JRE 次要更新之间发生了变化 2 一个标志否定另一个标志 3 特定系统上给定任意标志的默认值是什么 由 Java 人体工程学设置
  • Java VM 突然退出且没有明显原因

    我的 Java 程序突然退出 没有抛出任何异常 也没有正常完成 这是一个问题 我正在写一个程序来解决欧拉计划 http projecteuler net s 这就是我得到的 private static final int INITIAL
  • 如何使用IntelliJ IDEA ThreadDumpVisualizer插件分析Java线程转储

    我正在寻找使用一些线程转储分析器来分析 Java 线程转储并安装了ThreadDumpVisualizerIntelliJ IDEA 插件 但不知道如何使用它 插件页面 https plugins jetbrains com plugin
  • 病毒或机器故障导致“无法创建Java虚拟机”?

    我用的是双核XP机安装了 4GB 内存 但仅2 5GB由于 32 位事实 由操作系统报告 我正在积极修改旧的 JAVA 应用程序至少一个月 使用最新的Eclipse 编辑 构建和运行 和Ant 另一种构建和运行的方式 在里面Eclipse运
  • JVM 规范更新

    JVM 规范第 2 版的日期是 1999 年 自那时以来 我应该考虑学习哪些重要更新 如动态调用 这当然是为了了解现代 JVM 实现的内部原理 特别是 HotSpot 访问此链接http wikis sun com display HotS
  • 显示JVM中当前运行的所有线程组和线程

    所以我的任务是显示所有线程组以及当前在 JVM 中运行的属于这些组的所有线程 输出时应首先显示线程组 然后在下面显示该组中的所有线程 这是针对所有线程组完成的 目前 我的代码将仅显示每个线程组 然后显示每个线程 但我不确定如何达到我所描述的
  • Jprofile可以连接到docker中运行的JVM

    我是 JProfiler 的新手 我最近遇到了一个问题 我的Java应用程序在docker中运行 这意味着JVM在docker中运行 但我的jprofile安装在主机上 我知道 jprofiler 必须连接到 JVM 那么 jprofile
  • 如何减少Scala中创建的对象数量?

    我正在 Scala 中编写一个计算机图形应用程序 它使用 RGB 类返回图像中某个点的颜色 正如你可以想象的 返回颜色 RGB 对象的函数被调用了很多次 class RGB val red Int val green Int val blu
  • 一个好的 Java VM 中方法调用的开销是多少?

    有人可以提供反汇编的机器代码汇编程序列表吗 我的意思是 与 C 中的普通函数调用相比 肯定有一些开销 VM 需要跟踪调用以查找热点 并且当它使用编译代码时 如果新加载的类需要重新编译 它需要提供动态更改编译方法的方法 我想某处也有返回堆栈溢
  • Intellij Idea 使用什么 JVM 来启动?

    我是 Eclipse 用户 最近决定尝试 Intellij Idea 我的操作系统是 Ubuntu 12 使用 Eclipse 时 可以通过在 eclipse ini 中指定来轻松选择用于启动 Eclipse 的 JVM http wiki
  • 在 HP Load Runner 的 VuGen 中加载 javai.dll 时出现错误

    当我尝试在 HP load runner 的 VuGen 中编译一个简单的脚本时 无法启动 JVM 并出现以下错误 Java VM Internal Error Getting Error Loading javai dll 我在用着 HP
  • 为什么不在下一个 JVM 中删除类型擦除呢?

    Java 在 Java 5 中引入了泛型类型擦除 因此它们可以在旧版本的 Java 上运行 这是兼容性的权衡 我们已经失去了这种兼容性 1 https stackoverflow com questions 22610400 a progr
  • Scala 对大数的阶乘有时会崩溃,有时不会

    以下程序经过编译和测试 有时返回结果 有时充满屏幕 java lang StackOverflowError at scala BigInt apply BigInt scala 47 at scala BigInt equals BigI
  • 如何判断我是在 64 位 JVM 还是 32 位 JVM 中运行(在程序内)?

    如何判断应用程序运行的 JVM 是 32 位还是 64 位 具体来说 我可以使用哪些函数或属性来在程序中检测到这一点 对于某些版本的 Java 您可以使用标志从命令行检查 JVM 的位数 d32 and d64 java help d32
  • 为什么 MetaSpace 大小是已用 MetaSpace 的两倍?

    我写了一个程序来模拟MetaSpace OOM 但我发现MetaSpace Size几乎总是两倍大Used MetaSpace Why 我用标志运行我的程序 XX MaxMetaspaceSize 50m 程序抛出OOM时Used Meta
  • 强制jvm返回本机内存[重复]

    这个问题在这里已经有答案了 我时不时地运行需要大量内存的 eclipse 任务 因此 当任务运行时 jvm 会消耗大约 2 3GB 的 RAM 这是可以的 但是一旦 jvm 占用了该内存 它就不会释放它 并且我遇到了一种情况 堆中已用内存约
  • JVM内存段分配

    好吧 我有一个关于 JVM 内存段的问题 我知道每个 JVM 都会选择稍微不同地实现这一点 但这是一个总体概念 在所有 JVM 中应该保持相同 一个在运行时不使用虚拟机执行的标准C C 程序在运行时有四个内存段 代码 堆栈 堆 数据 所有这
  • OQL 包中的所有实例

    是否有可能在OQL检索属于一个包的所有对象 或者我可以查询wildcards 正如 haridsv 建议我尝试过的 SELECT from com example and SELECT a from com example but in V

随机推荐

  • keil5编译程序出错:runtime error R6002 -floating point support not loaded

    本想使用JTAG仿真器 43 Keil5试一下在线调试和下载程序 xff08 之前一直使用USB串口下载 xff09 xff0c 然后再编译时发现报错 xff0c 无法找到相应的下载文件 axf xff08 类似于无法生成一个下载到板子里面
  • 修改 docker 容器的启动参数等信息

    背景 docker 容器在之前启动时 xff0c 指定了 cmd 启动参数和挂载目录等配置 后来因为业务需要 xff0c 需要变更启动参数或挂载目录等信息 处理方法 1 停止所有 docker 容器 span class token fun
  • Java 并发高频面试题:聊聊你对 AQS 的理解?

    一 写在前面 这篇文章 xff0c 我们来聊聊面试时一个比较有杀伤力的问题 xff1a 聊聊你对AQS的理解 xff1f 之前有同学反馈 xff0c 去互联网公司面试 xff0c 面试官聊到并发时就问到了这个问题 当时那位同学内心估计受到了
  • 自从上了Prometheus,睡觉真香!

    文章来源 xff1a https c1n cn ojbYT 目录 学习目标任务背景任务要求任务分析Prometheus 实战 学习目标 如下 xff1a 能够安装 prometheus 服务器能够通过安装 node exporter 监控远
  • 面试官问我有没有高并发架构经验,我慌的一批…

    目录 一 1 道面试题的背景引入二 先考虑一个最简单的系统架构三 系统集群化部署四 数据库分库分表 43 读写分离五 缓存集群引入六 引入消息中间件集群七 现在能hold住高并发面试题了吗八 本文能带给你什么启发 xff1f 一 的背景引入
  • 我只是把握好了这3点,1个月后成功拿下大厂offer!

    目录 一 写在前面二 技术广度的快速准备三 技术深度的快速准备四 基础功底的快速准备五 下篇预告 一 写在前面 春节过后 xff0c 即将迎来的是一年一度的金三银四跳槽季 假如你准备在金三银四跳槽的话 xff0c 那么作为一个Java工程师
  • 程序员简历上写这种项目,难怪面试当炮灰。。。

    目录 xff1a 高级工程师必备 xff1a 系统设计能力如何让你的项目更有技术含量 上篇文章 我只是把握好了这3点 xff0c 1个月后成功拿下大厂offer xff01 我们聊了聊Java工程师在跳槽前的1个月 xff0c 如何利用较短
  • 程序员不了解这些投简历的巨坑,面试注定一开始就失败!

    目录 前言第一阶段 xff1a 练手第二阶段 xff1a 冲刺第三阶段 xff1a 收尾 前言 之前写了两篇文章 xff0c 给大家介绍了一下如何利用短期的时间 xff0c 尽可能充分的为面试做准备 xff1a 1 我只是把握好了这3点 x
  • 用真实业务场景告诉你,高并发下如何设计数据库架构?

    目录 xff1a 用一个创业公司的发展作为背景引入用多台服务器来分库支撑高并发读写大量分表来保证海量数据下查询性能读写分离来支撑按需扩容及性能提升高并发下的数据库架构设计总结 这篇文章 xff0c 我们来聊一下对于一个支撑日活百万用户的高并
  • 分布式唯一ID的几种生成方案,一次性全掌握!

    上一篇文章 xff0c 我们聊了一下分库分表相关的一些基础知识 xff0c 具体可以参见 xff1a 用真实业务场景告诉你 xff0c 高并发下如何设计数据库架构 xff1f 这篇文章 xff0c 我们就接着分库分表的知识 xff0c 来具
  • 程序员别死背面试八股文了,这种面试题才是未来主流。。。

    目录 xff1a 面试官为啥要出这样一个开放式问题生产消费模型及核心数据结构支撑TB级数据写入的分布式架构数据宕机场景下的高可用架构支持数据不丢失的ack机制最后的总结 1 面试官为啥要出这样一个开放式问题 这篇文章简单给大家来聊一个互联网
  • 面试官问我微服务注册中心如何保证数据强一致性?头秃了。。。

    目录 1 再回顾 xff1a 什么是服务注册中心 xff1f 2 Consul服务注册中心的整体架构3 Consul如何通过Raft协议实现强一致性 xff1f 4 Consul如何通过Agent实现分布式健康检查 xff1f 1 再回顾
  • Linux 时间同步 chrony

    介绍 Chrony 是NTP xff08 Network Time Protocol xff0c 网络时间协议 xff0c 服务器时间同步的一种协议 xff09 的另一种实现 xff0c 与ntpd不同 xff0c 它可以更快且更准确地同步
  • 字节面试官: 让你设计一个MQ每秒要抗几十万并发,怎么做?

    目录 1 页缓存技术 43 磁盘顺序写2 零拷贝技术3 最后的总结 这篇文章来聊一下Kafka的一些架构设计原理 xff0c 这也是互联网公司面试时非常高频的技术考点 Kafka是高吞吐低延迟的高并发 高性能的消息中间件 xff0c 在大数
  • 35岁高龄程序员的 4 条出路,提早布局,避免出局!

    目录 一 40岁回首往事 xff1a 自己竟没有任何核心优势二 公司遇到危机时40岁大龄程序员会怎么样三 适合大龄程序员的几条职业发展路线四 最后的寄语 这篇文章 xff0c 给大家聊聊Java工程师的职业发展规划的一些思考 xff0c 同
  • 面试官让我聊聊 MQ 的数据丢失问题,没想到水这么深。。。

    目录 一 背景引入二 Kafka分布式存储架构三 Kafka高可用架构四 画图复现Kafka的写入数据丢失问题五 Kafka的ISR机制是什么 xff1f 六 Kafka写入的数据如何保证不丢失 xff1f 七 总结 一 背景引入 这篇文章
  • 面试官:请设计一个能支撑百万连接的系统架构!

    目录 1 到底什么是连接 xff1f 2 为什么每次发送请求都要建立连接 xff1f 3 长连接模式下需要耗费大量资源4 Kafka遇到的问题 xff1a 应对大量客户端连接5 Kafka的架构实践 xff1a Reactor多路复用6 优
  • 二本学历5年经验的程序员,出去面试被碾压~

    目录 1 从一个求职案例引入2 学历差距 xff1a 面试官的第一印象3 公司背景差距 xff1a 你的人生名片4 技术差距 xff1a 硬核能力的欠缺5 架构能力的差距6 面试结果的分析 这篇文章 xff0c 聊一个很多人感兴趣的话题 x
  • 连你女朋友都能看懂的分布式架构原理!

    目录 从一个新闻门户网站案例引入推算一下你需要分析多少条数据 xff1f 黄金搭档 xff1a 分布式存储 43 分布式计算 这篇文章聊一个话题 xff1a 什么是分布式计算系统 xff1f 一 从一个新闻门户网站案例引入 现在很多同学经常
  • 面试官: 你们生产环境的JVM怎么设置的?

    前言 这篇文章 xff0c 给大家聊一个生产环境的实践经验 xff1a 线上系统部署的时候 xff0c JVM堆内存大小是越大越好吗 xff1f 先说明白一个前提 xff0c 本文主要讨论的是Kafka和Elasticsearch两种分布式