java学习(二) -----对象的初始化和清理

本文探讨了Java中对象初始化的过程以及在内存管理中的空间分配担保机制。在Minor GC时,JVM会检查晋升到老年代的对象平均大小与老年代剩余空间的关系,决定是否触发Full GC。如果平均大小大于剩余空间,将执行Full GC;若小于且允许,将不执行,以确保内存的有效使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java中的对象大多都是分配在堆上的,那么对象的创建和清理主要是针对堆来说的。
一、对象创建过程:

1. 当首次创建类型为Dog的对象时,或者Dog类的静态方法/静态域首次被被访问时,java解释器查找classPath,定位到Dog.class文件。
 
2. 载入Dog.class文件,生成一个Class类型对象,所有有关的静态初始化动作都会执行:如静态代码块,静态成员属性。 并且这种初始化动作只在Class对象首次加载时候进行一次。
 
3. 当用new Dog()创建对象时,首先JVM在堆heap上为Dog对象分配足够的存储空间。
 
4. 存储空间清空,自动将Dog对象中的所有基本类型数据都设置成了默认值,对象引用被设置为null。
 
5. 执行所有在字段定义处的一些初始化操作。
 
6. 调用构造器方法。
初始化过程:
静态变量/静态块-->非静态变量/非静态块---->方法(指构造方法)
二、垃圾回收
回答如下问题
1、如何判断对象是活的,对象是该被回收的。
答:两个方法判断:
引用计数法:这种方式对于循环引用的对象会出现对象该被回收,但是引用计数不为0。
根搜索算法:以gc-roots为对象的起点,从这些点乡下搜索所有走过的路径为引用链,当一个对象到gcRoots没有引用链相连时,则证明该对象是不可用的。
引用:下一的理解是如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,则这块内存代表着一个引用。
概念扩充之后:
强引用:垃圾回收器永远不会回收
软引用:还有用但并非必需的对象,在系统将要发生内存溢出之前,会对这些对象进行回收。
弱引用:还有用但并非必需的对象,存活到下次垃圾回收发生之前。
虚引用:对对象的生存时间不构成任何影响,目的是该对象被回收时可以收到系统通知。
2、如果不被引用,一定会死亡?
答:不一定,对象还有一次拯救复活的机会。如果没有与gcRoots相连接的引用链,那么将会被第一次标记并判断司法需要执行finalize()方法(当对象没有覆盖finalize方法或该方法已经被JVM执行过则判读为不需要执行),需要执行的对象被放入F-Queue中排队执行finalize(),如果该对象成功拯救自己,则第二次标记时,将会被溢出"即将回收"的集合。
垃圾回收算法
1、标记-清除:会产生两个问题,效率问题,在标记之后进行逐个清除效率太低,空间问题,清除之后会产生大量内存碎片。
2、复制算法:分为Eden和Survivor   比率为8:1  新生代使用此算法,当survivor空间不够用时,老年代进行兜底。
3、标记-整理:和标记-清除算法一张,只不过该算法后续步骤是将所有对象都移至一端,然后直接清楚端边界以外的内存。
垃圾收集器
1、serial收集器 单线程 stop the world 在client模式下的默认新生代收集器。
2、ParNew收集器 是serial的多线程版本stop the world 
3、CMS(concurrent mark sweep) 标记-清除  和应用线程同时进行
   分为4个阶段
   初始标记:标记gcRoots能直接关联到的对象,速度快。stop the world
   并发标记:标记gc Roots Tracing的过程,速度慢
   重新标记,为了修正并发标记期间因用户程序继续运作导致标记变动的对象的标记记录。stop the world
   并发清楚
缺点:对cpu资源比较敏感,例如如果只有一个cpu的话,因线程不断切换导致还没有单线程清除速度快。
     无法处理浮动垃圾,可能出现concurrent mode failure失败而产生另一次的full gc(serialold收集器进行老年代收集)
     标记-清除,产生内存碎片。
内存分配策略与回收策略(什么时候进行Minor gc 和full gc)
1、优先再Eden分配,若Eden空间不足,则引发一次 Monor gc
2、大对象直接进入老年代,大对象可能会导致内存空间不少,但不得不触发垃圾收集以获取足够的连续空间,所以日常开发中应避免定义大对象(字符串,数组)
3、长期存活的对象将进入老年代(熬过一次survivor年龄就增一岁,当年龄=15岁时,就晋升到老年代)
4、动态对象年龄判断:根据survivor空间中相同年龄的所有对象大小的总和大于survivor空间的一般,则大于或等于该年龄的对象直接进入老年代。

5、空间分配担保,发生Minor gc时,JVM会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间,如果大于,则进行full gc。如果小于,则看是否运行担保失败,如果允许,则不进行full gc。反之,则进行。

参考:《Java编程思想》 《深入理解Java虚拟机》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值