【一个Java文件从编码到执行要经过以下流程】【JVM内存分区】【一个对象的创建过程】【垃圾回收算法】

【一个Java文件从编码到执行要经过以下流程】

1、编译:将.java文件编译成.class文件;
2、加载:将.class文件加载到JVM内存中,会经过装载(把class的信息读到内存来)-》连接(连接阶段会对class的信息进行验证、为类变量分配内存空间并对其赋默认值)-》初始化操作(执行初始化静态块内容,并且为静态变量进行真正的赋值操作);
3、解释:将.class文件解释成操作系统可识别的指令码;
4、执行:给系统硬件设备发送指令码执行操作。

【JVM内存分区】

源码经过编译、加载后最终这些信息在JVM在运行后是如何进行分类存储的?

根据各种数据的特性JVM从逻辑上把内存划分成了几个区域;
分别为方法区、虚拟机栈、本地方法栈、程序计数器、堆 5个区域。

1、方法区:JVM方法区是用于保存已经被虚拟机加载的类元信息
 (包括类的版本、字段、方法、接口和父类等信息)、运行时常量信息(static、final定义的常量)、
 字符串常量信息(String a="dfc")。

2、虚拟机栈:栈这部分区域主要是用于线程运行方法的区域,此区域属于线程私有的空间,
每一个线程创建后都会申请一个自己单独的栈空间,每一个方法的调用都会对应着一个栈帧。
栈帧里存储着方法的局部变量表(保存着变量的数据)、操作数栈(进行运算时存放数据的空间)、
动态连接(指向常量池的引用)和方法返回地址(当前方法返回后的数据存放的地方)信息。
每调用一个方法都会生成一个新的栈帧,调用方法的过程就是一个压栈和出栈的过程。

3、本地方法栈:由于java需要与一些底层系统如操作系统或某些硬件交换信息时的情况,这个时候就需要
通过调用native本地方法来实现,本地方法栈和虚拟机栈功能差不多,区别在于本地方法栈是虚拟机调用
native方法时使用的。

4、程序计数器:程序计数器是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的
行号指示器,程序计数器记录着某个线程当前执行指令的位置,此区域属于线程隔离区。

5、堆内存主要是用来存放我们运行过程中创建的对象数据,根据对象所生存时间长短的特性在逻辑上分为
 新生代和老年代。


对于JVM而言,大部分对象都是属于一个朝生夕死的状态,这部分对象随着方法的调用而创建,
方法的结束而消亡,只有少部分的对象会长久的留在JVM 内存中,所以根据这样的特性JVM 把内存分为了
新生代 和老年代两个区,一般情况新创建的对象会放到新生代中,只有经过一定次数的GC后还没有被回收的对象,
我们认为这部分对象在未来也会长时间存在,所以会把这部分的对象转移到老年代的区域中去。
新生代分为eden区(存放新创建的对象)和suivior区(分为S1和S2)

【一个对象的创建过程】

1、编译:经过编译后Person.java 会生成一个Person.class文件。

2、装载:Person.class经过加载后,会把类的相关信息加载到JVM内存中,
解析出类的描述信息会保存到Metaspace,同时这里会生成一个代表这个类的java.lang.Class对象,
作为这个类的各种数据的访问入口。

3、连接:连接阶段会对静态变量的值进行默认赋值,此时Person类的staicVariabl 赋值为0;

4、初始化:
   1)、首先会对Person类的静态变量staicVariabl 进行真正的赋值的操作(此时staicVariabl =1)。
   2)、然后收集类的静态代码块内容,生成一个类的<clinit>() 方法并执行(此时staicVariabl =2)。
   
5、对象创建:
 1、构建对象:首先main线程会在栈中申请一个自己的栈空间,然后调用main方法后会生成一个main方法的栈帧。
 2、初始化对象:然后执行对象内部生成的init方法,初始化成员变量值,同时执行搜集到的{}代码块逻辑,
 最后执行对象构造方法。
 3、引用对象:对象实例化完毕后,再把栈中的Person对象引用地址指向Person对象在堆内存中的地址。

【垃圾回收算法】

一、不会被再次使用的对象我们就称之为垃圾

二、如何判断对象是否可以被回收?

1、引用计数法
引用计数法是为对象添加一个引用计数器,

2、可达性分析法
可达性分析法是通过以所有的“GC Roots”对象为出发点,如果无法通过GC Roots的引用追踪到的对象,
那我们认为这些对象就不会再次被使用了,现在主流的程序语言都是通过可达性分析法来判断对象是否存活的。

三、垃圾回收算法

1、标记清除法
标记清除法是先找到内存里的存活对象并对其进行标记,然后统一把未标记的对象统一的清理。
但是会造成不连续的内存空间。

2、标记复制法
首先它把内存划分出三块区域,一块用于存放新创建的对象叫Eden区,另外两块则用于存放存活的对象
分别叫 S1区和S2区。回收的时候会有两种情况,一种是把Eden和S1区的存活对象复制到S2区,
第二种是把Eden和S2区的存活对象复制到S1区 ,也就是说S1区和S2这两块区域同时只会有一块使用,
通过这种方式保证始终会有一块空白的q区域用于下次GC时存放存活的对象,而且原来的区域不需要
考虑保留存活的对象,所以可以直接一次性清除所有对象,这要既简单直接同时也保证了清除的内存区域
的内存连续性。

3、标记整理法
标记整理法分为标记和整理两个阶段,标记阶段会先把存活的对象和可回收的对象标记出来;
标记完再对内存对象进行整理,这个阶段会把存活的对象往内存的一端移动,移动完对象后
再清除存活对象边界之外的对象。

四、各种垃圾回收算法的适用场景

我们了解了三种垃圾回收算法后会发现,没有一个算法是完美,每种算法都有自己的特点,所以我们只能根据具体的场景去选择合适的垃圾收集算法。

1、标记清除法
特点: 简单、收集速度快,但会有空间碎片,空间碎片会导致后面的GC频率增加。
适合场景:只有小部分对象需要进行回收的,所以标记清除法比较适用于老年代的垃圾回收,因为老年代一般存活对象会比回收对象要多。

2、标记复制法
特点:收集速度快,可以避免空间碎片,但是有空间浪费,存活对象较多的情况下复制对象的过程等会非常耗时,而且需要担保机制。
适合场景: 只有少量对象存活的场景,这也正是新生代对象的特点,所以一般新生代的垃圾回收器基本都会选择标记复制法。

3、标记整理法
特点: 相对于标记复制法不会浪费内存空间,相对标记清除法则可以避免空间碎片,但是速度比其他两个算法慢。
适合场景: 内存吃紧,又要避免空间碎片的场景,老年代想要避免空间碎片问题的话通常会使用标记整理法。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值