JVM
文章平均质量分 81
JVM
二狗家有矿
这个作者很懒,什么都没留下…
展开
-
面试官:哪些场景会产生OOM?怎么解决?
什么时候会抛出OutOfMemery异常呢?初看好像挺简单的,其实深究起来考察的是对整个JVM的了解,而且这个问题从网上可以翻到一些乱七八糟的答案,其实在总结下来基本上4个场景可以概括下来。一、堆内存溢出堆内存溢出太常见,大部分人都应该能想得到这一点,堆内存用来存储对象实例,我们只要不停的创建对象,并且保证GC Roots和对象之间有可达路径避免垃圾回收,那么在对象数量超过最大堆的大小限制后很快就能出现这个异常。写一段代码测试一下,设置堆内存大小2M。publicclassHeap..转载 2021-04-02 11:43:25 · 256 阅读 · 0 评论 -
Java超神之路-JVM
一、ClassLoader类加载器1、类加载过程加载将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在内存上创建一个java.lang.Class对象用来封装类在方法区内的数据结构作为这个类的各种数据的访问入口。验证主要是为了确保class文件中的字节流包含的信息是否符合当前JVM的要求,且不会危害JVM自身安全,比如校验文件格式、是否是cafe baby魔数、字节码验证等等。准备为类变量分配内存并设置类变量(是被static...转载 2021-03-16 00:17:02 · 360 阅读 · 0 评论 -
[OOM] hbase堆外内存溢出底层定位
下文所说的 hbase client 版本,如无特指,则皆为 1.2.3。之前项目中出现堆外内存溢出(排查过程),虽然已经解决了问题,但当时没有深究底层的原理,最近抽空从底层入手,深入研究了 hbase client 读写源码,配合 jmeter 压测特定接口,并使用 mat 等工具分析,最终定位到了 hbase 堆外内存溢出的根本原因,本次就梳理下完整的过程,以及涉及的一些原理,防止以后踩坑。一.溢出现象单台服务器刚发布时 java 进程占用3g,以一天5%...转载 2021-03-12 10:46:24 · 707 阅读 · 1 评论 -
记一次堆外内存溢出排查过程
一、内存溢出现象异常堆栈:top 信息:现象描述:服务器发布/重启后,进程占用内存 21% 3g 左右,观察进程占用内存,以一天5%左右的速度增长,一定时间过后,java 进程内存增长到接近 90%,服务器报警。此时 old 区内存在 50%左右,由于未达到 CMS GC 的阈值,因此不会触发 CMS GC,而导致服务器内存溢出崩溃。JVM配置:8核16GJVM 参数: -Xms8g (初始化堆内存8g)-Xmx8g (最大堆内存8g)-Xmn3g (young 区转载 2021-03-12 10:42:45 · 2403 阅读 · 0 评论 -
【JVM】JMM与JVM关系(附整体架构图)
本文的目的,搞懂三个问题:JMM和硬件的关系? JMM如何保证并发编程三个重要特征? JVM内存区域和JMM的关系?1.硬件架构假如是要设计Java虚拟机,那么最先要分析的一定是计算机硬件情况。由于CPU速度快,所以在内存之前会有一个CPU缓存(一般分为L1,L2,L3),所以这时就会存在内存与CPU缓存一致性的问题。解决方案一:总线加锁(BUS),但是会降低CPU吞吐量 解决方案二:MESI 协议。比如,当CPU在CACHE中操作数据时,如果该数据是共享变量,数据在CACHE读转载 2021-02-23 09:06:29 · 711 阅读 · 0 评论 -
【JVM】监控调优(四):GC调优实操(gceasy)
JVM 调优主要就是调整下面两个指标: 停顿时间:垃圾收集器做垃圾回收中断应用执行的时间。-XX:MaxGCPauseMillis 吞吐量:运行用户代码时间/(运行用户代码时间+垃圾收集时间)。-XX:GCTimeRatio=n 停顿时间越短就越适合需要和用户交互的程序,良好的响应速度能提升用户体验;高吞吐量则可以高效地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。GC调优步骤:1)打印GC日志(注:Tomcat可以直接加载JAVA_OPTS变转载 2021-02-23 09:05:35 · 17378 阅读 · 0 评论 -
【JVM】监控调优(三):可视化工具
通过前两篇的介绍,参数也了解了,命令也知道了,关键是用起来不是很方便,要是有图形化的界面就好了。1.jconsoleJConsole工具是JDK自带的可视化监控工具。查看java应用程序的运行概况、监控堆信息、永久代使用情况、类加载情况等。启动方式:命令行输入 jconsole2.jvisualvm1)监控本地Java进程:可以监控本地的java进程的CPU,类,线程等2)监控远端Java进程:比如监控远端tomcat,演示部署在阿里云服务器上的tomcat在visu转载 2021-02-23 09:03:49 · 147 阅读 · 0 评论 -
【JVM】监控调优(二):JVM基本命令
在上一篇文章我们介绍了 JVM 常用参数,下面我们就来看看有哪些基本命令。1.jps查看java进程。结果为进程ID和进程名2.jinfo查看环境信息,实时查看和调整JVM配置参数1)查看 java 系统属性等同于System.getProperties()。格式:jinfo -sysprops 218802)查看JVM参数格式:jinfo -flag name PID (查看某个进程的name属性的值)jinfo -flag MaxHeapSi转载 2021-02-23 09:02:16 · 78 阅读 · 0 评论 -
【JVM】监控调优(一):JVM常用参数
首先,如何查看 JVM 参数?java -XX:+PrintFlagsFinal -version > flags.txt # 将参数打印到 flag.txt 文件后面还有很多参数,这里就不一一列出来了。值得注意的是"=“表示默认值,”:="表示被用户或JVM修改后的值要想查看某个进程具体参数的值,可以使用jinfo,这块后面聊。一般要设置参数,可以先查看一下当前参数是什么,然后进行修改1.标准参数-version-help-server-cp2.-X参数转载 2021-02-23 09:00:55 · 164 阅读 · 0 评论 -
【JVM】关于GC必须知道的几个问题
1.内存泄漏与内存溢出的区别?内存泄漏:对象无法得到及时的回收,持续占用内存空间,从而造成内存空间的浪费。 内存溢出:内存泄漏到一定的程度就会导致内存溢出,但是内存溢出也有可能是大对象导致的。2.young gc会有stw吗?不管什么 GC,都会有 stop-the-world,只是发生时间的长短。3.major gc和full gc的区别?major gc指的是老年代的gc,而full gc等于young+old+metaspace的gc。4.G1与CMS的区别是什么?CMS转载 2021-02-23 08:58:50 · 149 阅读 · 0 评论 -
【JVM】GC(四):GC日志格式解析
后面会结合实例来说明,先准备一个jar包,这里我拿的是一个启动 eureka 的 SpringBoot 项目。启动成功后在浏览器验证能够正常访问:那下面我们就分别配置不同的垃圾收集器,然后分析它们的日志内容。PS:打印GC日志的JVM参数是:-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-XX:+PrintGCDateStamps-Xloggc:./gc.log -jar1.Parallel Scavenge收集器(默认)因为 Paral...转载 2021-02-23 08:57:31 · 267 阅读 · 0 评论 -
【JVM】GC(三):垃圾收集器
在前面两篇文章,我们分别介绍了垃圾回收判断和回收算法本篇我们就来看看这些算法的具体实践者–垃圾收集器。Java 虚拟机规范对垃圾收集器应该如何实现没有任何规定,因为没有所谓最好的垃圾收集器出现,更不会有万金油垃圾收集器,只能是根据具体的应用场景选择合适的垃圾收集器。1.串行收集器只能有一个垃圾回收线程执行,用户线程暂停。 适用于内存比较小的嵌入式设备 。1.1 Serial(young)Serial(串行)收集器收集器是最基本、历史最悠久的垃圾收集器了。大家看名字就知道这个收集器转载 2021-02-22 23:30:31 · 185 阅读 · 0 评论 -
【JVM】GC(二):垃圾回收算法
在上一篇文章,我们介绍了什么时候情况下就可以回收垃圾了,但是回收的时候应该怎么做呢?基本的垃圾回收算法有以下四种:1.标记-清除算法它是最基础的收集算法,这个算法分为两个阶段,“标记”和”清除“。首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。它有两个不足的地方:效率问题,标记和清除两个过程的效率都不高; 空间问题,标记清除后会产生大量不连续的碎片;2.标记整理根据老年代的特点提出的一种标记算法,标记过程和“标记-清除”算法一样,但是后续步骤不是直接对可回收对象进转载 2021-02-22 23:29:31 · 82 阅读 · 0 评论 -
【JVM】GC(一):垃圾回收判断
GC是由JVM自动完成的,根据JVM系统环境而定,所以时机是不确定的。 当然,我们可以手动进行垃圾回收, 比如调用System.gc()方法通知JVM进行一次垃圾回收,但是具体什么时刻运行也无法控制。也就是说 System.gc()只是通知要回收,什么时候回收由JVM决定。 但是不建议手动调用该方法,因为消耗的资源比较大。一般以下几种情况会发生垃圾回收:(1)当Eden区或者S区不够用了 (2)老年代空间不够用了 (3)方法区空间不够用了 (4)System.gc()1.对象回收堆中几乎放着所有转载 2021-02-22 23:27:47 · 179 阅读 · 0 评论 -
【JVM】堆(Heap)上有什么?Class对象到反射
在文章开头,我们先看看反射是什么?Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法 可以简单理解为,在运行状态下,控制台输入一个(全)类名就可以得到一个该类对象,或者获取到该类的信息 可以实现类的动态加载 对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。 而这也是Java被视为动态或准动态语言的一个关键性质。(为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Per转载 2021-02-22 23:27:00 · 137 阅读 · 0 评论 -
【JVM】堆(Heap)上有什么?普通对象全方位解析
1.对象存储布局一个Java对象在内存中包括3个部分:对象头、实例数据和对齐填充1.1 对象头Mark Word状态标识。与虚拟机位数一样,一般64bit,32bit很少。下图是一个32位虚拟机的Mark Word示例:从对象头中可以获取到两点信息:Minor GC年龄默认15,是因为分代年龄只有4bit,最大就是15 有锁状态无HashCode是因为没空间存了Klass Pointer指针,指向相应类信息的地址(方法区)。大小也是由虚拟机位数决定,但 64bit 时由于转载 2021-02-22 23:25:30 · 236 阅读 · 0 评论 -
【JVM】底层实现(三):对象初始化流程 --init 方法、cinit 方法
Java 的两种类内变量初始化方式:成员变量:在实例构造器<init>方法中进行,比如 int x = 1 类变量:在类构造器<cinit>方法中或者使用 class ConstantValue 属性,static int x = 1:这里再多说一句,对于 static 变量的初始化,目前 Sun Javac 编译器的选择是:如果同时使用 final 和 static 来修饰一个变量,并且这个变量的数据类型是基本类型或者 java.lang.String 的话,就生成 C..转载 2021-02-22 23:24:27 · 402 阅读 · 0 评论 -
【JVM】底层实现(二):创建一个对象的过程
定义两个简单的类AAA和BBB通过javap -c AAA查看编译之后的字节码,具体如下:new 指令的实现过程Java 中的 new 关键字对应 jvm 中的 new 指令,定义在 InterpreterRuntime 类中PS:其中 pool是 AAA 的 constant pool,此时 AAA 的 class 已经加载到虚拟机中,new 指令后面的#2表示BBB类全限定名的符号引用在constant pool的位置1.pool->klass_at方法pool转载 2021-02-22 23:23:16 · 204 阅读 · 0 评论 -
【JVM】底层实现(一):浅谈 OOP-Klass 对象模型
当我们在写 Java 代码的时候,我们会面对着无数个接口,类,对象和方法。但我们有木有想过,Java 中的这些对象、类和方法,在 HotSpot JVM 中的结构又是怎么样呢?HotSpot JVM 底层都是 C++ 实现的,那么 Java 的对象模型与 C++ 对象模型之间又有什么关系呢?今天就来分析一下 HotSpot JVM 中的对象模型:oop-klass model。1.OOP-Klass 模型概述HotSpot JVM 并没有根据 Java 实例对象直接通过虚拟机映射到新建的 C++ 对转载 2021-02-22 23:22:13 · 497 阅读 · 0 评论 -
【JVM】Java 中的三种常量池
在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着来区分一下这几个概念。1.全局字符串池(string pool也有叫做string literal pool)全局字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到 string pool 中.记住:string pool中存的是引用值而不是具体的转载 2021-02-22 08:59:37 · 282 阅读 · 0 评论 -
【JVM】整体结构(三):执行引擎
在前面两篇文章,我们介绍了类加载子系统和运行时数据区【JVM】整体结构(一):类加载子系统 【JVM】整体结构(二):运行时数据区本篇我们就来看看 JVM 的最后一个部分,执行引擎。JVM 的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被JVM锁识别的字节码指令、符号表和其他辅助信息。那么,如果想让一个Java程序运行起来,这就涉及到了JVM的字节码执行引擎。执行引擎其实就是个运算器,能识别输入的转载 2021-02-22 08:53:45 · 87 阅读 · 0 评论 -
【JVM】整体结构(二):运行时数据区
在上一篇文章我们介绍了类加载子系统,在类的加载阶段的第(2),(3)步可以发现有运行时数据,堆,方法区等名词(2):将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 (3):在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口说白了运行时数据区就是类文件被类装载器装载进来之后,类中的内容(比如变量,常量,方法,对象等这些数据)得要有个去处,也就是要存储起来,存储的位置肯定是在JVM中有对应的空间1.Method Area(方法区)转载 2021-02-21 22:00:29 · 162 阅读 · 0 评论 -
【JVM】整体结构(一):类加载子系统
Java 虚拟机(java virtual machine,JVM),一种能够运行 Java 自己 Emma 的虚拟机。作为一种编程语言的虚拟机,实际上不只是专用于 Java 语言,只要生成的编译文件匹配JVM对加载编译文件的格式要求,任何语言都可以由 JVM 编译运行。比如 kotlin、scala等。JVM有很多,不只是Hotspot,还有Jrockit、J9等等。JVM主要由三个主要的子系统构成:类加载子系统,运行时数据区(内存结构),执行引擎。本篇我们先来看类加载子系统。Java 之转载 2021-02-21 21:59:18 · 78 阅读 · 0 评论 -
【JVM】指令助记符总结及基本指令大全
Java 虚拟机的指令由以下格式的字节码指令构成:操作码(Opcode 1 字节)[操作数(Oprand)],具有以下两个特点:由于 Java 虚拟机采用面向操作数栈而不是寄存器的架构,所以大多数的指令都不包含操作数,只有一个操作码。 class 文件中放弃了对操作数的长度做对齐,节约了填充和间隔符号需要的空间,但是为了在运行时从字节中重建出具体数据的结构,损失了一些执行效率。下面对所有指令做个总结(在查找时直接ctrl+F找相应命令): 变量到操作数栈:iload,iload_,lload,转载 2021-02-21 21:58:25 · 2289 阅读 · 0 评论 -
【JVM】class字节码文件结构详解
Java 之所以可以“一次编译,到处运行”,一是因为 JVM 针对各种操作系统、平台都进行了定制(JRE),二是因为无论在什么平台,都可以编译生成固定格式的字节码(.class文件)供JVM使用。因此,也可以看出字节码对于Java生态的重要性。那到底什么是字节码?之所以被称之为字节码,是因为字节码文件由十六进制值组成,而JVM以两个十六进制值为一组,即以字节为单位进行读取(1字节 = 8个二进制位,1个十六进制位 = 4个二进制位)。PS:除此之外,由于 JVM 规范的存在,只要最终可以生成符合规转载 2021-02-21 21:57:13 · 495 阅读 · 0 评论