淮安谁家做网站,广州网上注册公司网站,营销网店推广的软文,做社交网站多少钱4、运行时数据区
4.1、运行时数据区介绍 运行时数据区也就是JVM在运⾏时产生的数据存放的区域#xff0c;这块区域就是JVM的内存区域#xff0c;也称为JVM的内存模型——JMM 堆空间#xff08;线程共享#xff09;#xff1a;存放new出来的对象 元空间#xff08;线程共…4、运行时数据区
4.1、运行时数据区介绍 运行时数据区也就是JVM在运⾏时产生的数据存放的区域这块区域就是JVM的内存区域也称为JVM的内存模型——JMM 堆空间线程共享存放new出来的对象 元空间线程共享存放类元信息、类的模版、常量池、静态部分 线程栈线程独享⽅法的栈帧 本地⽅法区线程独享本地⽅法产⽣的数据 程序计数器线程独享配合执⾏引擎来执⾏指令
4.2、程序在执行时运行时数据区中的内存变化
⾸先在程序的.class目录内执行如下命令查看程序具体的汇编指令
javap -c JVMAnalyze得到结果
Compiled from JVMAnalyze.java
public class com.qf.jvm.JVMAnalyze {public com.qf.jvm.JVMAnalyze();Code:0: aload_01: invokespecial #1 // Method java/lang/Object.init:()V4: returnpublic int add();Code:0: bipush 102: istore_13: bipush 205: istore_26: iload_17: iload_28: iadd9: bipush 1011: imul12: istore_313: iload_314: ireturnpublic static void main(java.lang.String[]);Code:0: new #2 // class com/qf/jvm/JVMAnalyze3: dup4: invokespecial #3 // Method init:()V7: astore_18: aload_19: invokevirtual #4 // Method add:()I12: istore_213: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;16: iload_217: invokevirtual #6 // Method java/io/PrintStream.println:(I)V20: return
}通过指令JMM内存发⽣了如下变化 线程栈执行⼀个方法就会在线程栈中创建⼀个栈帧。 栈帧包含如下四个内容 局部变量表存放方法中的局部变量操作数栈用来存放方法中要操作的数据动态链接存放方法名和方法内容的映射关系通过方法名找到方法内容方法出口记录方法执行完后调用此方法的位置。
5、对象的创建流程
5.1、对象创建流程 5.2、类加载校验
校验该类是否已被加载。主要是检查常量池中是否存在该类的类元信息。如果没有则需要进⾏加载。
5.3、分配内存
为对象分配内存。具体的分配策略如下 Bump the Pointer指针碰撞如果内存空间的分配是绝对规整的则JVM记录当前剩余内存的指针在已用内存分配 Free List空闲列表如果内存空间的分配不规整那么JVM会维护⼀个可用内存空间的列表用于分配。
对象并发分配存在的问题 Compare And Swap自旋分配如果并发分配失败则重试分配之后的地址 Thread Local Allocation BufferTLAB本地线程分配缓冲JVM为每个线程分配⼀块空间每个线程在自己的空间中创建对象jdk8默认使⽤之前版本需要通过-XX:UseTLAB开启
5.4、设置初值
根据数据类型为对象空间赋初始化值。
5.5、设置对象头
为对象设置对象头信息对象头信息包含以下内容类元信息、对象哈希码、对象年龄、锁状态标志等。
对象头中的Mark Work 字段32位 对象头中的类型指针Klass Pointer
类型指针用于指向元空间当前类的类元信息。比如调用类中的方法通过类型指针找到元空间中的该类再找到相应的方法。
开启指针压缩后类型指针只用4个字节存储否则需要8个字节存储
指针压缩
过大的对象地址会占⽤更大的带宽和增加GC的压力。
对象中指向其他对象所使⽤的指针8字节被压缩成4字节。 最早的机器是32位最大支持内存 2的32次方4G。现在是64位2的64次⽅可以表示N个T的内存。内存32G即等于2的35次方。如果内存是32G的话用35位表示内存地址这样过于浪费。如果把35位的数据根据算法压缩成32位的数据也就是4个字节。在保存时用4个字节再使用时使用8个字节。之前用35位保存内存地址就可以用32位保存。这样8个字节的对象实际上使用32位来保存这样64位就能表示2个对象。
如果内存⼤于32G指针压缩会失效会强制使用64位来表示对象地址。因此jvm堆内存最好不要大于32G。
Jdk1.6之后默认开启指针压缩可通过配置jvm参数关闭指针要锁 -XX:-UseCompressedOops
示例代码
package com.qf.jvm;import org.openjdk.jol.info.ClassLayout;import java.lang.String;/*** 对象指针压缩* author Thor* 公众号 Java架构栈*/
public class ObjectLengthAnalyze {public static void main(String[] args) {ClassLayout classLayout ClassLayout.parseInstance(new A());System.out.println(classLayout.toPrintable());}static class A{int num;String name;}
}
关闭指针压缩 开启指针压缩 5.6、执行init方法
为对象中的属性赋值和执⾏构造方法。
本文章参考B站 千锋教育JVM全套教程(含jvm调优、jvm虚拟机、jvm面试题、jvm源码详解)系统玩转java虚拟机全程干货无废话仅供个人学习使用部分内容为本人自己见解与千锋教育无关。