jvm

字节码增强

和自甴很熟 提交于 2020-01-28 20:10:47
之前看了美团技术团队推送的一篇文章,介绍了字节码增强技术,可的很好,自己也记录一下,增强一下记忆,也方便日后巩固学习,有兴趣的可以去搜索美团技术团队的原文 字节码是JVM的底层基础知识,如果能够掌握对于排查问题会有更深层次的理解 1.什么是字节码 首先我们看看什么是字节码,找到一个.class文件,看看长什么样子 Java之所以可以一次编译,到处运行,首先是因为JVM针对各种操作系统和平台都进行了定制,二是无论在什么平台,都可以通过javac命令将一个.java文件编译成固定格式的字节码(.class文件)供JVM使用 之所以被称之为字节码,是因为.class文件是由十六进制值组成的,JVM以两个十六进制值为一组,就是以字节为单位进行读取 2.字节码的结构 .java文件编译后生成的字节码文件,打开如上图,JVM对字节码是有规范要求的,要求每一个字节码文件都要有十部分按照固定的顺序组成,整体的结构和顺序如下图: (1)魔数 所有的.class文件的前4个字节都是魔数,魔数以一个固定值:0xCAFEBABE,放在文件的开头,JVM就可以根据这个文件的开头来判断这个文件是否可能是一个.class文件,如果是这个开头,才会往后执行下面的操作 一直困惑的java的图标为什么是一杯咖啡,看到这里就大概明白了,这个魔数的固定值是Java之父James Gosling指定的,意为CafeBabe

JVM常用命令

随声附和 提交于 2020-01-28 19:09:38
内存 -XX:MaxPermSize 设置永久代最大空间 -XX:PermSize 设置永久代大小 -Xms 设置堆最小值 -Xmx 设置堆最大值 -Xmn 设置新生代大小 -XX:NewSize 设置新生代大小 -XX:MaxDirectMemorySize 设置直接内存大小,默认是和xmx一样 -Xss 设置栈容量 -Xoss 设置本地方法栈大小,实际上无效 -XX:+/-UseTLAB 设置本地线程分配缓存(TLAB) -Xnoclassgc 是否回收方法区 查看类加载和卸载信息 -verbose:class -XX:+TraceClassLoading Product版虚拟机使用 -XX:+TraceClassUnLoading FastDebug版虚拟机使用 GC(minor GC(新生代GC) major GC(老年代GC) FullGC) -XX:+SurvivorRatio 设置eden和survivor比例,默认是8:1 -XX:+PretenureSizeThreshold 设置直接晋升老年代的大小,超过这个大小的不进入新生代 -XX:+MaxTenuringThreshold 设置晋升到老年代的年龄,就是经过多少次GC后还活着的对象进入老年代 -XX:+UseAdaptiveSizePolicy 使用自动大小适配,不需要手动设置新生代、老年的大小 -XX

Java的GC,类加载机制

让人想犯罪 __ 提交于 2020-01-28 11:47:54
目录 JVM的内存结构 1.方法区(Method Area) 2.堆区(Heap) 3.虚拟机栈(VM Stack) 4.本地方法栈(Native Method Stack) 5.程序计数器(Program Counter Register) JVM类加载过程 1.加载 2.连接 2.1.验证 2.2.准备 2.3.解析 3.初始化 4.类加载的时机 5.类加载器 类加载机制 GC机制 1.查找算法(判断对象是否存活) 1.1.生存还是死亡 2.内存分区 3.1.判断对象是否存活算法 4.GC算法 Serial收集器 CMS收集器 JVM的内存结构 根据JVM规范,JVM把内存划分成了如下几个区域: 1.方法区(Method Area) 方法区存放了要加载的类的信息(如类名、修饰符等)、静态变量、构造函数、final定义的常量、类中的字段和方法等信息。方法区是全局共享的,在一定条件下也会被GC。当方法区超过它允许的大小时,就会抛出OutOfMemory:PermGen Space异常。 在Hotspot虚拟机中,这块区域对应持久代(Permanent Generation),一般来说,方法区上执行GC的情况很少,因此方法区被称为持久代的原因之一,但这并不代表方法区上完全没有GC,其上的GC主要针对常量池的回收和已加载类的卸载。在方法区上进行GC,条件相当苛刻而且困难。 运行时常量池

jvm原理 jvm构成 gc垃圾回收

試著忘記壹切 提交于 2020-01-28 10:41:03
JVM 文章目录 JVM JVM是什么? JVM怎么实现跨平台的? 浅谈JRE JDK JVM的位置 JVM的构成 运行时数据区 栈 堆 方法区 程序计数器 本地方法栈 类加载机制 什么是类加载机制? 类加载器 双亲委派机制 JVM调优 JVM的生命周期 GC垃圾回收机制 垃圾回收的原因 GC常见算法 可达性分析算法 标记清除算法 复制算法 标记整理算法 终极算法 ( 分代收集算法 ) JVM是什么? ​ JVM是Java Virtual Machine(Java 虚拟机 )的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 JVM怎么实现跨平台的? JVM 只能认识字节码,也就是他只认识xxx.class 这种类型的文件,并将它们解释到系统的 API 调用。针对不同的系统有不同的 jvm 实现,有 Linux 版本的 jvm 实现,也有 Windows 版本的 jvm 实现,但是同一段代码在编译后的字节码是一样的。引用上面的例子,在 Java API 层面,我们调用系统声音设备的代码是唯一的,和系统无关,编译生成的字节码也是唯一的。但是同一段字节码,在不同的 jvm 实现上会映射到不同系统的 API 调用,从而实现代码的不加修改即可跨平台运行。 浅谈JRE JDK JRE(Java Runtime

day1

限于喜欢 提交于 2020-01-28 00:20:36
学习的知识有点杂乱,今天看的一些面试问题。虽然是重述,但也是通过自己能理解的语言复述,旨在保持一种写博客的习惯,等开始做项目会慢慢记录更多。 (1)java程序运行过程:在java语言开发环境中编写.java文件通过java编译器编译形成.class(字节码),JVM使用类加载器加载.class文件,类加载器完成后,进行字节码检验,字节码检验通过后,JVM解释器会把字节码翻译成机器码交由操作系统执行。 (2)jdk,jre,JVM之间的区别:jdk是java的开发环境(将java文件编译成class文件)与运行环境(解析class文件),jdk中包含了jre,jre是java运行环境,是java的最小运行单元,一般安装服务器上,jre中包含了JVM,jre中有java核心库,JVM具有跨平台特性,屏蔽底层的服务器差异运行一套java程序,JVM是java程序的载体(目前对虚拟机的了解比较浅) 来源: CSDN 作者: 沐之。 链接: https://blog.csdn.net/qq_35449051/article/details/104095114

深入理解JVM:内存区域

a 夏天 提交于 2020-01-27 22:08:42
一、运行时数据区域 Java虚拟机在运行时java程序的时候,会把它所管理的内存划分成若干个不同的数据区域。其中jdk1.8前后版本有差别。 jdk1.8之前: jdk1.8之后: 内存可分为:程序计数器、栈、堆、方法区和直接内存。 整个内存数据区域是属于当前进程的,当前进程拥有所有的资源和数据。而直接内存是所有进程共享的。 其中栈和程序计数器是线程私有的,也就是每一个线程拥有自己独立的区域。互相不干扰。 二、程序计数器 我们的java代码在程序执行之前就被编译成字节码。而这个程序计数器不是我们计算机组成原理的程序计数器(存放的计算机指令地址),而我们的jvm的pc是字节码解释器的指示器。存放的是字节码的地址。如果执行的是java方法,这里存储的就是正在执行的字节码的地址,如果执行的是本地方法存储的就是undefined。 字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完成。 在多线程的环境下,pc还能保证恢复到原来线程的位置。 注意:程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡。 三、Java虚拟机栈 描述的是 Java 方法执行的内存模型,每次方法调用的数据都是通过栈传递的。 栈帧:操作数栈 动态链接

JVM基础课三:JVM调优

蹲街弑〆低调 提交于 2020-01-27 18:46:09
JVM调优 主要就是对JVM内存大小的分配设置,内存收集器的选择和参数调节配置,来达到控制GC次数和GC时间,提高应用响应时间和吞吐量的目的; JVM监控 JVM监测工具主要有:jps,jstat,jinfo,jmap,jhat,jconsole,virtualVM,linux可能需要进入bin目录,用./执行; jps,jinfo用来分析启动参数,jstat,jmap用来分析实时情况,jconsole,virtualVM用来可视化分析; JPS jps -l -v 用来查看所有jvm进程,会展示” pid jar包 jvm参数“等信息,可以很方便用来查看应用启动情况,这也可以非常方便检查应用启动脚本是否生效; JSTAT jstat -class pid 用来查看当前pid进程的类加载情况; 加载11975个类,占据21KB Loaded Bytes Unloaded Bytes Time 11975 21647.2 0 0.0 8.99 jstat -gcutil pid 用来查看jvm内存使用情况(百分比); S0使用0%,S1使用34%,E使用32%,O使用31%,M使用95%,YGC 19次,总共0.21s,FGC3次,总共0.5s,gc总共0.75s S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 34.04 32.72 31.37

JVM学习笔记-运行时数据区

北慕城南 提交于 2020-01-27 04:33:58
   不同于C,C++程序,Java程序的内存管理工作由Java虚拟机(JVM)接管,这减低了java程序员的负担,但如果出现内存泄露与溢出问题如报OutOfMemory,StackOverFlow异常错误时,如果不了解JVM虚拟机的内存管理细节,往往很难快速定位错误。   JVM在运行时会把其所管理的内存分为几个不同的数据区域,分别为:程序计数器,虚拟机栈,本地方法栈,堆,方法区等。这些区域存放的数据不同,功能也不同。   JVM管理的内存包含以下几个运行时数据区: 1.程序计数器   程序计数器是一块较小的内存空间,可将其视为当前线程所执行字节码的行号指示器。为了线程切换后能恢复到正确执行的位置,每条线程都需要有单独的程序计数器,使各线程之间互不干扰,独立存储。因此该区域是线程私有区。   值得一提的是,该区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError异常的区域。 2.Java虚拟机栈   Java虚拟机栈也是线程私有的。虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从调用直至执行完成的过程,就是一个栈帧在虚拟机栈中入栈出栈的过程。   局部变量表存放了编译期可知的各种基本数据类型(boolean,byte,char,int,short,float

JVM系列之------类的加载机制

天涯浪子 提交于 2020-01-27 04:09:21
java的类加载机制 我们知道,Java源文件是不能直接在虚拟机上面执行的,java虚拟机不和java在内的任何语言绑定,它只和“Class文件”这种特定的二进制文件有所关联,我们的java语言如果想在虚拟机上面执行,就必须要编译成.class形式的文件,虚拟机会把描述类的数据从class文件加载到内存。 也就是说,一个java源文件如果被执行的话,需要经历以下过程: 对于虚拟机把的.class文件加载到内存这一过程,如果这个class文件被修改过,如果class文件格式不正确的话,虚拟机还能正常加载吗,如果有同名的类Class文件,该如何加载呢? 何为虚拟机类加载机制: 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化、最终形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制。 在java语言里,类型的加载、连接、初始化都是在程序运行期间完成的,这个策略是java作为可以动态扩展的语言、为程序提供高度的灵活性的保障。比如说java中多态的体现,一个接口可以等到运行时再指定实际的实现类。 类从加载到虚拟机主要经历了以下几个阶段: 一、加载 “加载”是类加载过程的一部分,在加载阶段,虚拟机需要以下三个步骤: 通过一个类的全限定名来获取此类的二进制流; 将这个二进制流所代表的静态存储结构转化为方法区的运行时数据结构;

JVM--堆内存调优

左心房为你撑大大i 提交于 2020-01-27 03:36:54
堆参数 常用参数: - Xms -- jvm堆的最小值 - Xmx -- jvm堆的最大值 - XX : MaxNewSize -- 新生代最大值 - XX : MaxPermSize = 1028 m -- 永久代最大值 - XX : + PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式) - XX : + PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013 - 05 - 04 T21 : 53 : 59.234 + 0800 ) - XX : + PrintGCDetails -- 打印出GC的详细信息 - verbose : gc -- 开启gc日志 - Xloggc : d : / gc . log -- gc日志的存放位置 - Xmn -- 新生代内存区域的大小 - XX : SurvivorRatio = 8 -- 新生代内存区域中Eden和Survivor的比例 Java7: Java8: JDK1.8之后将最初的永久代取消了,由元空间取代。 元空间与永久代最大的区别在于: 永久代使用的JVM的堆内存,但是Java8以后的元空间并不在虚拟机中而是使用本机物理内存。 因为,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入native memory,字符串池和类的静态变量放入java堆中