jvm虚拟机基本概念

1. JVM 运行时数据区域

1 方法区

保存类信息、常量、静态变量

2 程序计数器

虚拟机字节码指令的地址

3 java栈

描述java方法内存模型,包括局部变量、操作数栈、动态链接等信息。局部变量包括类型:boolean byte char short int long double float、对象引用、方法返回类型。如果线程请求的栈深度大于虚拟机的栈深度,会报错StackOverFlow;如果申请内存失败,会报错OOM。

4 java堆

特性:
1. 内存最大的区域
2. 所有对象分配的地方
3. 分为新生代和老生代,垃圾回收的主要区域
4. 可以处理物理上不连续,逻辑上连续
5. 空间不足以分配对象实例会oom

2. 对象分配

步骤:
1. new Object(),检查常量池中是否声明了类Object,且Object类是否已经加载,如果没有加载,则开始加载Object类。
2. 进入堆分配内存操作。
3. 线程安全问题,两种解决方案:1.加上同步锁;2.ThreadLocal上分配。
3. 虚拟机对象默认的分配内存为0
4. 初始化对象头,包括:类型信息、哈希码、GC年代
5. 初始化实例字段

3. 垃圾收集算法

分代:
1. 标记清除算法。无法解决循环引用的问题,目前虚拟机都没有采用这个算法。没有内存碎片问题。
2. 拷贝算法。优点:提升了回收的速度。缺点:内存只能使用一半,拷贝开销大。
3. 标记压缩算法。解决了内存碎片问题。

根据对象声明周期进行分代的架构:

1.新生代:Eden,Survivor。

2.老年代

不同生命周期的对象回收使用不同的回收算法。

大部分对象生命周期都比较短暂,创建以后就会销毁。存活的对象被临时放入eden区域,采用拷贝算法进行回收。eden区域被拷贝15次的对象被认为是长生命周期对象,给放入old分区。这部分对象会随着时间的增加逐渐增多,采用标记压缩的回收算法。

4. 类加载机制

4.1 类的加载过程

类加载过程分为:装载,验证、准备、解析,初始化。

类加载的触发条件:
1. new对象
2. 引用类的静态变量
3. 引用类的静态方法
4. 反射调用
5. 初始化一个类,如果父类没有初始化,首先要初始化父类

被动引用的场景,在此场景下类不会被初始化:

  1. 当访问一个类的静态成员变量,只有真正声明这个变量的类会被初始化。比如该成员变量在父类中声明,那么就会初始化父类,不会初始化子类。
  2. 声明一个类为类型的数组,不会初始化这个类。比如A[] array = new A[];
  3. 访问类的常量,不需要初始化类。类的常量是在编译阶段就初始化预存在常量池里面。

4.2类加载器种类

  1. 引导类加载器:负责加载java的核心库,c实现
  2. 扩展类加载器:负责加载java的扩展类库,java实现
  3. 应用类加载器:负责加载应用程序,java实现
  4. 自定义类加载器,java实现

猜你喜欢

转载自blog.csdn.net/rambomatrix/article/details/78143867