JVM内核调优(一)

一、JVM模型

 方法区:类加载器加载的class,常量,静态变量

堆区:new Object()

二、class文件二进制字节码

魔数:CA FE BA BE四个字节表示class文件标识

次版本号:魔数的后两位字节

主版本号:次版本号的后两位字节

javap -v xxx.class 反编译查看class文件的详细信息

三、运行数据区

1、程序计数器

 记录程序执行的位置,每个线程独有的

程序计数器,没有任何溢出异常

2、虚拟机栈

任何一个方法进去,它都是一个栈帧。

栈上分配对象:

根据逃逸分析,方法里面new出来的对象没出方法,那么这个对象就在栈上分配。

好处是,减少垃圾回收的次数。默认是开启逃逸分析的,如果关闭逃逸分析,则对象是在堆中分配。

注:栈上分配对象也是有大小限制的,一个栈的默认大小是1m

栈的溢出异常:递归时,报栈的深度溢出错误

3、堆

jdk1.7的堆模型

年轻代+老年代+永久代(存类的相关信息)

jdk1.8的堆模型

年轻代+老年代+元空间(不在jvm内部,属于本地内存)

4、方法区

是jvm的一种规范,元空间和永久代实现了方法区

注意:字符串常量池不在元空间,而是在堆内分配。

四、类加载的过程

1)类的加载就是将class文件中的二进制数据读取到内存中,然后将该字节流 所代表的静态数据结构转化为方法区中运行的数据结构,并且在堆内存中生成 一个java.lang.Class对象作为访问方法区数据结构的入口。

加载到内存的过程是类加载器完成的,涉及到的加载器从上往下有 系统类加载器,扩展类加载器,应用类加载器,自定义加载器。这些加载器涉及到双亲委派机制,防止核心类被篡改,覆盖。

2)验证class文件格式:这个好理解,就是验证加载的字节码是不是符合规范 是不是CAFEBABYE开头 主次版本号是否在当前jvm虚拟机可运行的范围内 常量池类型对不对 有没有其他不可识别的信息 ……等

 元数据验证:到java语法级别了。这个阶段主要验证属性、字段、类关系、方法等是否合 规 是否有父类?除了Object其他类必须有 是否继承了不该被继承的类,比如final 是不是抽象类,是的话,方法都完备了没 字段有没问题?是不是覆盖了父类里的final ……等

字节码验证:最复杂的一个阶段。 等等,字节码前面不是验证过了吗?咋还要验证? 上面的验证是基本字节表格式验证。而这里主要验证class里定义的方法, 看方法内部的code是否合法。 类型转换是不是有问题? 指令是否跳到了方法外的字节码上?

符号引用验证:最后一个阶段。 这个阶段也好理解,我们上面的字节码解读时,知道字节码里有的是直接 引用,有的是指向了其他的字节码地址。 而符号引用验证的就是,这些引用的对应的内容是否合法。 utf8里记了某个类的名字,这个类存在不? 方法或字段引用,这些方法在对应的类里存在不存在? 类、字段、方法等上面的可见性是否合法

(3)准备阶段:这个阶段为class中定义的各种类变量分配内存,并赋初始值。

(4)解析阶段:解析阶段开始解析类之间的关系,需要关联的类被加载。

(5)初始化阶段,给类变量赋最终的值

五、实例化对象的过程

1、在方法区找对应的类信息

2、在当前方法的栈帧的本地变量表中放置一个reference指针

3、在堆中开辟一个内存空间,保存对象的实例

4、将指针指向堆中的对象的地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值