前面提到了虚拟内存需要映射物理内存才能使用,这个映射关系被保存在内存中的页表(Page Table)。现代 CPU 架构中一般有 TLB (Translation Lookaside Buffer,翻译后备缓冲,也称为页表寄存器缓冲)存在,在里面保存了经常使用的页表映射项。TLB 的大小有限,一般 TLB 如果只能容纳小于 100 个页表映射项。 我们能让程序的虚拟内存对应的页表映射项都处于 TLB 中,那么能大大提升程序性能,这就要尽量减少页表映射项的个数:页表项个数 = 程序所需内存大小 / 页大小。我们要么缩小程序所需内存,要么增大页大小。我们一般会考虑增加页大小,这就大页分配的由来,JVM 对于堆内存分配也支持大页分配,用于优化大堆内存的分配。那么 Linux 环境中有哪些大页分配的方式呢?
Java 凭借着自身活跃的开源社区和完善的生态优势,在过去的二十几年一直是最受欢迎的编程语言之一。步入云原生时代,蓬勃发展的云原生技术释放云计算红利,推动业务进行云原生化改造,加速企业数字化转型。
在实际的业务场景中,我们往往倾向于认为容器环境与虚拟机一样,可以完全自定义不同参数的虚拟 CPU 和虚拟 Memory 资源。其实,从本质上而言,容器更倾向于一种隔离机制环境,其中一个进程的资源( CPU、内存、文件系统、网络等)与另一个进程隔离。这种隔离是可能的,因为 Linux 内核中有一个名为 CGroups 的特性。然而,一些从执行环境收集信息的应用程序在 CGroup 存在之前就已经实现了。像大多数常用的命令行 “top”、“free”、“ps” 等诸如此类的工具,甚至 JVM 都没有针对在容器内执行进行优化,毕竟,容器是一个高度受限的 Linux 进程。
当我们将 JVM 生态中的关键要素,例如,垃圾收集器、堆大小和运行时编译器设置默认值时,许多技术人员(开发、运维人员)或许应该意识到在 Linux 容器生态中(诸如,Docker、Rkt、RunC、Lxcfs 等)内所运行的 Java 进程的实际行为与预期不符。当我们在没有任何调优参数(例如,最为简洁的的启动命令行:“ java -jar myapplication .jar”)的情况下执行 Java 应用程序时,JVM 将自行调整某些特定的参数,以在当前执行环境中获得最佳性能表现。
不同的 GC 堆大小动态伸缩有很大很大的差异(比如 ParallelGC 涉及 UseAdaptiveSizePolicy 启用的动态堆大小策略以及相关的 UsePSAdaptiveSurvivorSizePolicy、UseAdaptiveGenerationSizePolicyAtMinorCollection 等等等等的参数参与决定计算最新堆大小的方式以及时机),在这个系列以后的章节我们详细分析每个 GC 的时候再详细分析这些不同 GC 的动态伸缩策略。我们这里仅涉及大多数 GC 通用的堆大小伸缩涉及的参数:MinHeapFreeRatio 与 MaxHeapFreeRatio:
OpenJDK 9中首次新增了一项实验性功能,JVM可借助该功能检测到自己运行在容器中,进而酌情调整内存限制。尽管过去几年来容器技术日渐流行,但包括JVM在内的很多工具依然需要通过宿主机的参数访问可用
-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M
_NullPointer 出处:https://www.cnblogs.com/renwei/
分别复制tomcat目录下的 conf logs temp webapps work 这5个目录到 test1 和 test2下。
今天,内网测试服务器A总是运行一段时间就服务器进程自行退出了,给出了“Java Result :137”这样的错误码。上网查了一下这个137,感觉没有啥有价值的东西。一开始怀疑项目中的JNI调用崩溃到底层,但是没有看到core.*这样的崩溃日志,同时也没有发现OOM的日志,也没有常见的Java 的堆异常log,关键是同样的环境,另外一台机器B,压力远比这个大,都稳定运行很长时间没有问题。下午又崩溃了两三次,一度怀疑Java是不是有什么bug,不过这个想法立马被我否认了,先从自己找原因。
在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约 600m,Linux自身使用大约800m。从表面上,物理内存应该
采用zip或tar.gz的二进制包方式安装的ES,需要配置一系列参数,通过阅读官方文档了解到其中重要参数的配置及其说,下面将逐步进行了解。
JVM 调优是一个很大的话题,在回答“如何进行 JVM 调优?”之前,首先我们要回答一个更为关键的问题,那就是,我们为什么要进行 JVM 调优?
Java 19 中 Loom 终于 Preview 了,虚拟线程(VirtualThread)是我期待已久的特性,但是这里我们说的线程内存,并不是这种 虚拟线程,还是老的线程。其实新的虚拟线程,在线程内存结构上并没有啥变化,只是存储位置的变化,实际的负载线程(CarrierThread)还是老的线程。
在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约 600m,Linux自身使用大约800m。
(2)stack - 输出当前方法被调用的调用路径, 一个方法被执行的路径非常多,不知道这个方法是从那里被执行,就可以采用
看泉子的一篇文章:JVM源码分析之Jstat工具原理完全解读 - 你假笨 里提到了两个JVM参数,可以控制perfdata文件是否共享,引用泉子对这两个参数的解释:
要添加在tomcat 的bin 下catalina.sh 里,位置cygwin=false前 。
引言 在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约600m,Linux自身使用大约800m。从表面上,物理内存
在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约 600m,Linux自身使用大约800m。从表面上,物理内存应该是足够使用的;但实际运行的情况是,会发生大量使用SWAP(说明物理内存不够使用 了),如下图所示。同时,由于SWAP和GC同时发生会致使JVM严重卡顿,所以我们要追问:内存究竟去哪儿了要分析这个问题,理解JVM和操作系统之间的内存关系非常重要。接下来主要就Linux与JVM之间的内存关系进行一些分析。 一、Li
在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约 600m,Linux自身使用大约800m。从表面上,物理内存应该是足够使用的;但实际运行的情况是,会发生大量使用SWAP(说明物理内存不够使用 了),如下图所示。由于SWAP和GC同时发生会致使JVM严重卡顿,所以我们要追问:内存究竟去哪儿了?
可以利用当前流行的监控工具,如Prometheus和Grafana,以及JDK自带的命令行工具,例如jps、jstat、jinfo、jstack等,来分析JVM的运行状态。
在SpringBoot的Web项目中,默认采用的是内置Tomcat,当然也可以配置支持内置的jetty,内置有什么好处呢?
在SpringBoot的Web项目中,默认采用的是内置Tomcat,当然也可以配置支持内置的jetty,内置有什么好处呢? 1. 方便微服务部署。 2. 方便项目启动,不需要下载Tomcat或者Jetty
高级运行时选项(Advanced Runtime Options): -XX:+UnlockCommercialFeatures 开启商业选项,许多商业特性都需要这个选项的支持。 -XX:+CheckEndorsedAndExtDirs jdk 8中新增加的一个参数,有兴趣的可以去看看openjdk中的关于这一块的实现(http://hg.openjdk.java.net/jdk8u/hs-dev/hotspot/rev/fa6adc194d48) 这个参数是用来阻止Java 命令运行应用(除非没有用到endorsed-standards override机制&扩展机制)。 同时,这个选项会检查应用是否启动了以下机制 1、java.ext.dirs 或 java.endorsed.dirs 属性被设置 2、lib/endorsed 目录存在 && 不为空 3、lib/ext 目录下包含了除JDK以外的JAR 4、系统范围内 特定于平台的扩展目录中包含任何JAR文件 -XX:+DisableAttachMechanism 启动此参数之后,JVM将禁止任何工具连接,通常情况下这个选项是关闭的。外部工具指的是 jstack、jmap、jinfo等JVM辅助分析工具。 -XX:ErrorFile=filename 用于当出现致命错误时,指定一个目录,用来存储Error信息。默认为当前目录下的hs_err_pidpid.log,也就是 filename=./hs_err_pidpid.log -XX:+FailOverToOldVerifier 当新的类型检查失败时,自动使用老的验证器。默认这个是关闭的,但是当我们需要时使用老版本的字节码的时候则需要开启这个选项。 -XX:+FilghtRecorder 嗯。Java 就是性能记录。这是一个商业特性,和 -XX:+UnlockCommercialFeatures 选项一起使用如果这个选项开启了,那么JVM的性能记录是不可用的。 -XX:-FilghtRecorder 嗯,又是性能记录。关闭了 -XX:FilghtRecorderOptions={ parameter=value、 defaultrecording={true|false}、 disk={true|false}、 dumponexit={true|false}、 dumponexitpath=path、 globalbuffersize=size loglevel={quiet|error|warning|info|debug|trace} maxage=time maxchunksize=size maxsize=size repository=path samplethreads={true|false} settings=path stackdepth=depth threadbuffersize=size } defaultrecording: 指定是否在后台一只记录还是只运行一段时间,默认这个参数的值是false。如果要一直开启,请设置为true。 disk:是否JRE持续的把记录写到硬盘中,默认false,如果想要持续记录,需要设置为true。 dumponexit:是否在JVM终止的时候记录JFE的数据 dumponexitpath:JVM终止是记录JFE的数据的路径,如果指定的是一个目录 JVM会自动创建一个文件(文件名一般是以当前时间生成),若是文件名,如果这个文件名已经存在了,通常会加一个时间后缀来区分。这个参数如果不生效,上一个参数的选项也是不成立的 globalbuffersize=size:指定保留数据的总大小。 loglevel:JFE日志的日志级别,默认 Info maxage:设置数据对大的保留时间 maxchunksize=size:设置数据最大块的大小 maxsize=size:设置数据在硬盘的最大容量,默认容量没有限制,前提:仅当disk=true时,此选项可用。 respository=path:设置临时仓库,默认使用系统的临时路径 samplethreads:设置是否进行线程抽样,默认为true setting=path:设置事件配置文件,默认是使用JAVA_HOME/jre/lib/default.jfc stackdepth=depth:设置对应栈追踪的深度,默认深度为64 threadbuffersize=size:指定每个线程的本地缓冲的大小,默认大小为5k
不同的 GC 情况下,初始化以及扩展的流程可能在某些细节不太一样,但是,大体的思路都是:
在高并发下,Java程序的GC问题属于很典型的一类问题,带来的影响往往会被进一步放大。不管是「GC频率过快」还是「GC耗时太长」,由于GC期间都存在Stop The World问题,因此很容易导致服务超时,引发性能问题。
1、问题: 最近在往 HBase 写中文的时候,发现 hbase 查出来的数据会有部分中文乱码了,而部分中文又是正常的,按理来说,一般的乱码问题要么全乱,要么不乱。考虑到出现中文的地方都是来源于 hdfs 上的一个配置文件,而这个配置文件可以确定是 utf-8 编码的,那排除了原始文件导致的乱码,想想 MR 代码里也没有转码的逻辑,也排除了代码的问题,那就只有一种可能:Hadoop 集群的系统环境是异构的,这里面可能涉及到 linux 、java 的环境变量、配置的问题。 2、排查: (1)打印了整个集群的
前文我们没有提到,如何限制元空间的大小,其实就是限制 commit 的内存大小。元空间的限制不只是受限于我们的参数配置,并且前面我们提到了,元空间的内存回收也比较特殊,元空间的内存基本都是每个类加载器的 ClassLoaderData 申请并管理的,在类加载器被 GC 回收后,ClassLoaderData 管理的这些元空间也会被回收掉。所以,GC 是可能触发一部分元空间被回收了。所以元空间在设计的时候,还有一个动态限制 _capacity_until_GC,即触发 GC 的元空间占用大小。当要分配的空间导致元空间整体占用超过这个限制的时候,尝试触发 GC。这个动态限制也会在每次 GC 的时候动态扩大或者缩小。动态扩大以及缩小
原文地址:https://www.cnblogs.com/superfj/p/8667977.html
最开始的mqnamesrv.sh脚本获取环境变量的部分看不懂其实没啥影响,大略有个印象即可,当然可以截取部分的命令到Linux运行测试一下就明白了,比如准备环境变量等等,最后一句话比较关键。
Zabbix自带监控系统的内存利用率和CPU利用率,但是系统内存并不能反应JVM内存情况
该命令主要与jmap搭配使用,用来分析jmap转储的转储快照。其中构建了一个微型的http/html服务器。生成dump文件的分析结果后可以通过浏览器进行查看。 通常情况下不采用jhat进行分析,一方面,分析工作需要耗费额外的资源和时间,既然都要在其他机器进行,则不需要限定于上述工具。另外一方面,jhat界面比较简陋,可以用visualVM,eclipse的Memory Analizer 等更加专业的分析工具进行替换。
应用程序出现OOM异常,你是否仍然通过看日志的方式去排查问题(该方式定位解决问题是大概率的巧合而已)?正确的排查方案是进行dump文件分析,你知道为什么吗?
介绍 在SpringBoot的Web项目中,默认采用的是内置Tomcat,当然也可以配置支持内置的jetty,内置有什么好处呢? 1. 方便微服务部署。 2. 方便项目启动,不需要下载Tomcat或者Jetty 针对目前的容器优化,目前来说没有太多地方,需要考虑如下几个点 线程数 超时时间 jvm优化 针对上述的优化点来说,首先线程数是一个重点,初始线程数和最大线程数,初始线程数保障启动的时候,如果有大量用户访问,能够很稳定的接受请求, 而最大线程数量用来保证系统的稳定性,而超时时间用来保障
Linux 内存管理模型不是咱们这个系列的讨论重点,我们这里只会简单提一些对于咱们这个系列需要了解到的,如果读者想要深入理解,建议大家查看 bin 神(公众号:bin 的技术小屋)的系列文章:一步一图带你深入理解 Linux 虚拟内存管理
一、JVM内存模型及垃圾收集算法 1.根据Java虚拟机规范,JVM将内存划分为: New(年轻代) Tenured(年老代) 永久代(Perm) 其中New和Tenured属于堆内存,堆内存会从JVM启动参数(-Xmx:3G)指定的内存中分配,Perm不属于堆内存,有虚拟机直接分配,但可以通过-XX:PermSize -XX:MaxPermSize 等参数调整其大小。 年轻代(New):年轻代用来存放JVM刚分配的Java对象 年老代(Tenured):年轻代中经过垃圾回收没有回收掉的对象将被Cop
-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M 这里有几个问题: 1. 各个参数的含义什么? 2. 为什么有的机器我将-Xmx和-XX:MaxPermSize都设置为512M之后Eclipse可以启动,而有些机器无法启动? 3. 为何将上面的参数写入到eclipse.ini文件Eclipse没有执行对应的设置? 下面我们一一进行回答 1. 各个参数的含义什么? 参数中-vmargs的意思是设置JVM参数
-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M 这里有几个问题: 1. 各个参数的含义什么? 2. 为什么有的机器我将-Xmx和-XX:MaxPermSize都设置为512M之后Eclipse可以启动,而有些机器无法启动? 3. 为何将上面的参数写入到eclipse.ini文件Eclipse没有执行对应的设置? 下面我们一一进行回答 1. 各个参数的含义什么?
Linux系统中tomcat的启动参数 export JAVA_OPTS="-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CM
本篇原文作者是 LinkedIn 的 Swapnil Ghike,这篇文章讲述了 LinkedIn 的 Feed 产品的 GC 优化过程,虽然文章写作于 April 8, 2014,但其中的很多内容和知识点非常有参考意义。因此,翻译后献给各位同学。
jps位于jdk的bin目录下,其作用是显示当前系统的java进程情况,及其id号。 jps相当于Solaris进程工具ps。不象”pgrep java”或”ps -ef grep java”,jps并不使用应用程序名来查找JVM实例。因此,它查找所有的Java应用程序,包括即使没有使用java执行体的那种(例如,定制的启动 器)。另外,jps仅查找当前用户的Java进程,而不是当前系统中的所有进程。
概述 jps 命令类似与 linux 的 ps 命令,但是它只列出系统中所有的 Java 应用程序。 通过 jps 命令可以方便地查看 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息。
领取专属 10元无门槛券
手把手带您无忧上云