java中的Jvm

一.什么是jvm

java中的jvm又称java虚拟机。java之所以是跨平台的编程语言,和jvm有很大的关系。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。在引入了jvm后,java代码在不同的平台上运行不需要再重新编译,只需要编译成在jvm上运行的字节码文件,jvm会帮助我们把字节码文件翻译成在具体平台上的机器指令,这就是传说中的“一次编译,到处运行”。

二.jvm的内存模型

jvm在执行java代码时,把它管理的内存区域分为5个不同的区域,分别为堆,方法区,java虚拟机栈,本地方法栈和程序计数器。其中,堆和方法区是所有的线程所共享的,后三者是线程私有的。jvm划分的这5个区域,各有各的作用,共同管理内存。
在这里插入图片描述

  1. 程序计数器
    每个线程都有自己的程序计数器,它记录着当前线程执行到字节码文件的哪一行。如果执行的是本地方法,则它的值为null
  2. 虚拟机栈
    虚拟机栈占用是操作系统的内存,一个线程的方法在执行的时候,就会创建一个栈帧,栈帧中储存的是局部变量表,方法出口等,当方法被调用时,栈帧入栈,当方法执行完毕后出栈。
  3. 本地方法栈
    本地方法栈储存的是本地方法调用的状态,它于虚拟机栈唯一的区别就是,虚拟机栈是执行java方法的,而它是执行native方法的,在很多虚拟机中,会将本地方法栈和虚拟机栈放在一起使用。
  4. 方法区
    方法区中存放了要加载的类的信息,如类的信息(类名,修饰符等),类中的静态变量,常量,属性和方法信息。它也被称为是“永久代”,但在一定的条件下,也会被gc回收。需要注意的是,运行时常量池也在方法区中。

  5. 所有的对象实例和数组都要在堆上分配。它是垃圾回收器主要管理的区域。为了更好的回收,把堆分为新生代和老年代(1:2)。其中新生代又分为Eden空间和2个Survivor空间(8:1:1)。

三. 虚拟机中GC的过程

(s1代表“from Survivor”,s2代表“to Survivor”)
(判断一个对象是否存活简单的说就是判断这个对象是否被引用)

  1. 新创建的对象被分配在Eden区,它的内存空间是连续的,2个survivor空间是空的
  2. 当Eden区满了后,就触发minor GC,经过扫描和标记,把存活的对象复制到s1,不存活的对象被回收。
  3. 在下一次minor GC时,重复上一次操作,把存活的对象复制到s2,其余对象回收。其中,s1中存活的对象年龄加1。此时,eden区和s1区被清空,所有存活的对象复制到了s2区。
  4. 再下一次minor GC时,重复这个过程,保证Eden区和一个survivor是被清空的。
  5. 当存活中的对象的年龄在达到一个阈值时(默认是8,可配置),就会从年轻代移入老年代。
  6. 在发生minorGC时,虚拟机会检测老年代的剩余内存是否大于年轻代进入老年代的内存,如果小于,则执行Full GC。把老年代中没有引用的对象回收。
  7. Minor GC ,Full GC 触发条件
    Minor GC触发条件:当Eden区满时,触发Minor GC。

Full GC触发条件:
(1)调用System.gc时,系统建议执行Full GC,但是不必然执行
(2)老年代空间不足
(3)方法区空间不足
(4)通过Minor GC后进入老年代的平均大小大于老年代的可用内存
(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。

四. jvm中类加载的过程

类加载的过程包括了5个阶段:加载,验证,准备,解析和初始化

常量池:常量池中的数据在编译时就已被确定,储存了类,方法,接口等中的常量,字符串常量等。(和运行时常量池不同)
常量池中主要存放两大类常量:
字面量:文本字符串,声明为final的常量等。
符号引用:类和接口的完全限定名,字段的名称和描述,方法的名称和描述。

  1. 加载
    通过类的权限定名称获取这个类的二进制字节流,然后将其代表的静态存储结构转化为方法区的运行时数据结构,最后再堆区创建这个类的Class对象.
  2. 验证:确保Class中的字节流文件是否符合虚拟机的要求
  3. 准备:为类的静态变量分配存储空间,并赋予初始值。
  4. 解析:将常量池中的符号引用转化为直接引用。
  5. 初始化:执行java代码

五. jvm中对象的创建过程(new)

  1. 检查类是否被加载过,如果没有,则先加载类。
  2. 在堆中给对象分配内存
  3. 给分配的内存空间赋初始值
  4. 设置对象的头信息(对象的Gc年龄,哈希码等)
  5. 执行完new后,接着执行方法,按照代码进行初始化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值