淘宝自己网站怎么建设,重庆市最新工程项目,网站制作的分割线怎么做,天元建设集团有限公司单位代码预备
为了更好的理解类加载和垃圾回收#xff0c;先要了解一下JVM的内存区域#xff08;如果没有特殊说明#xff0c;都是针对的是 HotSpot 虚拟机。#xff09;。
Java 源代码文件经过编译器编译后生成字节码文件#xff0c;然后交给 JVM 的类加载器#xff0c;加载完…预备
为了更好的理解类加载和垃圾回收先要了解一下JVM的内存区域如果没有特殊说明都是针对的是 HotSpot 虚拟机。。
Java 源代码文件经过编译器编译后生成字节码文件然后交给 JVM 的类加载器加载完毕后交给执行引擎执行。在整个执行的过程中JVM 会用一块空间来存储程序执行期间需要用到的数据这块空间一般被称为运行时数据区也就是常说的 JVM 内存。
JVM的不断在发展所以内存区域的规范也在更新 看这个地方的时候总是不自觉的联想到操作系统的虚拟内存空间疑惑它们之间的区别这个博文JVM内存是对应到操作系统内存_jvm内存和电脑内存的关系_ManimalW的博客-CSDN博客解释了我的疑惑。 线程私有部分
程序计数器每个线程私有是一块内存区域存放下一个要执行的字节码指令的地址。程序计数器中存储的数据所占的空间不会随程序的执行而发生大小上的改变因此程序计数器是不会发生内存溢出现象OutOfMemory的问题
虚拟机栈每个线程私有存放栈帧方法调用时入栈结束时出栈
本地方法栈和虚拟机栈所发挥的作用非常相似区别是虚拟机栈为虚拟机执行 Java 方法 也就是字节码服务而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。 以上三者是线程私有也就是每个线程都有这样一块区域只存放自己的东西。
线程共享部分
堆heap是垃圾回收的主要区域从垃圾回收的角度来看由于垃圾收集器基本都采用了分代垃圾收集的算法所以会将堆细分。
在 JDK 7 版本及 JDK 7 版本之前堆内存被通常分为下面三部分
新生代内存(Young Generation)老生代(Old Generation)永久代(Permanent Generation)
其中永久代是方法区的具体实现《Java 虚拟机规范》规定了有方法区这么个概念和它的作用具体实现靠各种虚拟机。hotspot的实现就是永久代HotSpot 使用 GC分代来实现方法区内存回收。从jdk8开始变成了元空间放在了本地内存中存放。
总结一下区别 永久代和元空间是hotspot针对方法区不同的实现
永久代在堆空间中元空间在本地内存
永久代变成元空间后静态变量和字符串常量也被移动到了堆中存放
运行时常量池在方法区中在hotspot中就是元空间或者永久代中。运行时常量池用来动态获取类信息包括class文件元信息描述、编译后的代码数据、引用类型数据、类文件常量池等。
字符串常量池这个存放字符串常量创建字符串之前检查常量池中是否存在如果存在则获取其引用如果不存在则创建并存入返回新对象引用。 对象创建的过程
1.类加载检查 检查类有没有被加载初始化过如果没有 执行类加载过程
2.分配内存 为对象分配内存
3.初始化零值
4.设置对象头 例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外根据虚拟机当前运行状态的不同如是否启用偏向锁等对象头会有不同的设置方式。
5.执行init方法
对象访问定位
直接指针
栈中的引用存放的就是对象的地址
基于句柄
堆中划分一块区域作为句柄池池中存放的就是地址栈中的引用存放的时句柄的地址
面试题
介绍下 Java 内存区域运行时数据区Java 对象的创建过程五步建议能默写出来并且要知道每一步虚拟机做了什么对象的访问定位的两种方式句柄和直接指针两种方式