JVM---2

1. 子类和父类执行顺序

  • 类加载(如果没有初始化类加载,则执行)
  • 从字节码层面看:
  • 类对象的初始化:类的构造方法(收集静态变量+静态代码块)
  • 实例对象的初始化实例的构造方法(收集成员变量+实例代码块+Java层面的构造方法)
  • 从字节码层面看执行顺序
  1. 父类的初始化:父类的构造该方法
  2. 子类的初始化:子类的构造该方法
  3. 父类的实例对象的构造方法:父类的实例对象构造方法(收集父类的成员变量,实例代码块,Java的构造方法)
  4. 子类的实例对象的构造方法:子类的实例对象构造方法

2.内存泄漏

  • 内存泄漏:内存中,随着进程的运行时间越来越长,存放的无用的数据(变量/常量值,对象,类型)越来越多。可用内存空间越来越少。
  • 内存泄漏的结果:进程一直运行,有用户一直使用系统,随着时间的越来越长,最终一定会出现某个内存区域出现空间不足的问题(OOM)
  • 解决问题:
  1. 程序代码优化:如设置超时时间,超过了指定时长,定时清理长期不用的用户。(可以使用一些JVM的检测工具)
  2. 临时解决方案:有时候有老旧的大型项目,不太好优化(即使使用内存泄漏的检测工具,也不好定位)万能重启大法:隔一定的时间,重启java进程;如果隔的时间觉得太短,加内存。(如果系统内存不满足java进程所需要的内存,要加大系统内存)
  • 内存泄漏,随着使用时间越来越长,最终一定会出现OOM,但是OOM不一定是内存泄漏引起的。

3. 垃圾回收

  • Garbage Collection(GC),java 进程在启动后会创建垃圾回收线程,来堆内存中无用的对象进行回收。
  • 什么是垃圾?
  • 无用的对象(堆),常量(常量池),类型(方法区的类信息)
  • 关于垃圾回收:
  • Java进程启动——创建gc线程(垃圾回收器——回收——垃圾)
  • 垃圾回收器:
  1. 基于垃圾回收算法来执行回收工作;
  2. 不同的垃圾回收器,使用的算法不同
  3. 回收方法区,堆中的垃圾

3.1 垃圾回收的时机

  • 创建对象/常量/类加载,先需要在某个内存区域分配内存空间,如果空间不足,则执行gc,如果gc还不足,就是OOM。
  • java.lang.Object中有一个finalize()方法,当JVM确定不再指向该对象的引用时,垃圾回收器在对象上调用该方法。finalize()方法有点类似于对象周期的临终方法,JVM调用该方法,表示该对象即将"死亡",之后就可以会使用该对象了。注意回收还是在JVM中处理的,如果手动调用某个对象的finalize()方法,不会造成对象"死亡"。

3.2 判断垃圾的算法

3.2.1 引用计数算法

  • 有增加某个对象的引用,该对象引用计数器+1,减少计数器-1
  • 缺陷:无法解决循环引用的问题,主流的JVM中,都没有使用该算法
    在这里插入图片描述

3.2.2 可达性分析算法

  • 此算法的核心思想为:通过一系列称为" GC Roots"(线程运行时,局部变量(引用)指向的是一项)的对象作为起始点,从这些节点开始向下搜索(看对象中的成员变量,搜索走过的路径称之为"引用链",当一个对象到GC Roots没有任何的引用链相连时(从GC Roots到这个对象不可达)时,证明此对象是不可用的。
    在这里插入图片描述

3.3 回收的内存区域

3.3.1 回收方法区

  • 在1.7里面叫做方法区(Method Area),1.8称为元空间(Metaspace)
  • gc中,方法区称为永久代(方法区/元空间的概念,不是真实JVM实现的依赖,只是表达了要存放什么样的数据)
  • gc叫永久代,属于真实的jvm内部gc的实现时,使用的内存描述,
  • 虽然叫做永久代,但是不意味着对象在这块区域是永久存活的,还是可以回收,只是回收效率,效率都比较低。

3.3.2 回收堆

  • gc中,把堆也称为gc堆
    在这里插入图片描述

3.4垃圾回收算法

3.4.1 标记清除算法(老年代的回收算法)

  • 分为两个阶段:
  1. 标记:标记无用对象(使用不可达分析算法)
  2. 清除:清除标记的垃圾
  • 标记- 清除算法的不足主要有两个
  1. 效率问题:标记和清除两个过程的效率都不高
  2. 空间问题:标记清除后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行中需要分配较大的随想时,无法找到足够连续内存而不得不提前触发下一次的GC。

3.4.2 复制算法(新生代回收算法)

在这里插入图片描述

  • 优点:
  1. 新生代中的对象,大部分都是朝生夕死(创建出来以后,很快就不可达),复制存活对象,性能很高(存活对象很少)
    线程调用方法:方法中局部变量的方式创建对象,方法栈帧出栈(方法返回),堆中对象就不可达。
  2. 没有内存碎片的问题
  • 缺点:内存的利用率不高,只有50%
  • 复制算法的优化方案:提高新生代内存的利用率。
  • 将内存(新生代内存)分为一块较大的Eden(伊甸区)空间和两块较小的Survivor(幸存者)空间,每次使用Eden和其中的一块Survivor(两个Survivor区域称为一个From区,一个To区)HotSpot默认Eden与Survivor的大小比例是8:1,也就是说Eden:Survivor From :Survivor To = 8:1:1,所以每次新生代可用内存空间为整个新生代容量的90%,只有10%的会被浪费。

3.4.3标记整理算法(老年代的回收算法)

  • 对象存活率较高的情况使用。
  • 根据老年代的特点,提出了一种称之为"标记-整理算法",标记过程和标记清除算法中的标记是一样的,后续步骤不是直接对可回收对象进行清理,而是让所有的存货对象向一端移动,然后清理掉端边界以外的内存。
    在这里插入图片描述
  • 优点:没有内存碎片的问题。

3.4.4 分代收集算法

  • 属于一种算法思想,没有算法实现。具体来说,把堆话划分为好几块。
  • (新生代:Eden区,S0,S1),使用复制算法的升级版
  • (老年代):使用标记清除算法或者标记整理算法。
  • 新生代gc,又称为Yong GC ,minor GC (指对用户线程的影响较小),表现是:对象的存活率是较低的,回收效率非常高,效率也较高。
  • 老年代GC,又称为Old GC,major gc(指对用户线程影响较大),回收速度是比新生代慢10倍。
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值