先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
https://www.cnblogs.com/dolphin0520/p/3783345.html
我们先来了解一个最基本的问题:如果确定某个对象是“垃圾”?既然垃圾收集器的任务是回收垃圾对象所占的空间供新的对象使用,那么垃圾收集器如何确定某个对象是“垃圾”?———即通过什么方法判断一个对象可以被回收了。
public class Main {
public static void main(String[] args) {
MyObject object1 = new MyObject();
MyObject object2 = new MyObject();
object1.object = object2;
object2.object = object1;
object1 = null;
object2 = null;
}
}
class MyObject{
public Object object = null;
}
最后面两句将object1和object2赋值为null,也就是说object1和object2指向的对象已经不可能再被访问,但是由于它们互相引用对方,导致它们的引用计数都不为0,那么垃圾收集器就永远不会回收它们。
为了解决这个问题,在Java中采取了 可达性分析法。该方法的基本思想是通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。
也可以看:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版) 周志明 3.2章节
回收算法有3种:
2.2、标记-清除
通过可达性分析的方式来标记需要回收的对象。
清除后:
缺点:
-
堆中所有的对象都会被扫描一遍,从而才能确定需要回收的对象,比较耗时
-
有空间碎片,空间不连续,导致一些打的对象可能分配不到合适的空间,这样就还会触发GC回收,而GC回收是比较耗时的
2.3、标记-复制
清除后:
优点:不会有空间碎片;
缺点:浪费了一半的空间;
2.4、标记-整理
整理后:
堆:Old Young(Eden、S0和S1)
哪个算法用在哪个区域呢?
不同的代用不同的垃圾回收算法
Young区,复制 —> 前提条件:每次垃圾回收 存活的对象都比较少 —> 复制算法
绝大多数的对象都被回收掉了 —> 一般的对象都是朝生夕死的
垃圾回收的过程,GC日志 文章名:Understanding G1 GC Logs https://blogs.oracle.com/poonam/understanding-g1-gc-logs
结论:Young区使用复制算法是没有问题的。
Old区:一般是存活时间比较长的,意味着很难被回收 —>
当需要要回收的对象很少时,使用标记整理算法(只标记,不清除);
当需要回收的对象很多时,使用标记清除算法;
总结:
-
1、新生代: 新生代中的对象存活率低,只要付出少量的复制成本就能完成回收过程,因此选用复制算法;
-
2、老生代: 老生代中的对象存活率高,并且没有额外空间进行分配担保,因此选用 “标记 - 清理” 或 “标记 - 整理” 算法。
3、面试题
=====
1、简单讲一下Java的内存模型?
2、Java 的 GC机制
-
GC有多少种垃圾回收的算法?
-
你听说过 年轻代、老年代吗?
-
复制算法、标记清除 有了解过吗?
3、Java内存管理:常见的变量,在内存的不同区域,GC的回收;
-
我在new一个对象的时候,它是被放在内存的那一块区域;
-
成员变量和局部变量:在内存区域位置的区别和回收方面的区别;
3.1、简单讲一下Java内存模型【垃圾回收相关】。
JVM的运行时数据区包括线程私有(程序计数器、本地方法栈、虚拟机栈)和线程共享(堆、方法区)。
而内存模型的设计主要考虑线程共享区域,因为这两个区域存放的是所有线程共享的数据,因此数据会比较多,而线程私有的数据跟线程的生命周期有关,一旦线程被销毁,这些数据也就被回收了,因此不用过多关注。
而线程共享区域包含有堆和方法区,方法区也不用关注,因为方法区里面的内存分配和垃圾回收我们无法控制,那么我们只有一个区域需要关注了,那就是堆。
堆可分为老年代和新生代,新生代又分为Eden空间、From Survivor空间、To Survivor空间。(空间比例为8:1:1)。
3.2、简单讲一下新生代和老年代。
https://blog.csdn.net/jisuanjiguoba/article/details/80156781
堆可分为老年代和新生代,新生代又分为Eden空间、From Survivor空间、To Survivor空间。(空间比例为8:1:1)。
**1)年轻代(Young Gen):**年轻代主要存放新创建的对象,内存大小相对会比较小,垃圾回收会比较频繁。年轻代分成1个Eden Space和2个Suvivor Space(命名为A和B)。当对象在堆创建时,将进入年轻代的Eden Space。垃圾回收器进行垃圾回收时,扫描Eden Space和A Suvivor Space,如果对象仍然存活,则复制到B Suvivor Space,如果B Suvivor Space已经满,则复制到Old Gen。同时,在扫描Suvivor Space时,如果对象已经经过了几次的扫描仍然存活,JVM认为其为一个持久化对象,则将其移到Old Gen。扫描完毕后,JVM将Eden Space和A Suvivor Space清空,然后交换A和B的角色(即下次垃圾回收时会扫描Eden Space和B Suvivor Space。这么做主要是为了减少内存碎片的产生。
我们可以看到:Young Gen垃圾回收时,采用将存活对象复制到到空的Suvivor Space的方式来确保尽量不存在内存碎片,采用空间换时间的方式来加速内存中不再被持有的对象尽快能够得到回收。
**2)年老代(Tenured Gen):**年老代主要存放JVM认为生命周期比较长的对象(经过几次的Young Gen的垃圾回收后仍然存在),内存大小相对会比较大,垃圾回收也相对没有那么频繁(譬如可能几个小时一次)。年老代主要采用压缩的方式来避免内存碎片(将存活对象移动到内存片的一边,也就是内存整理)。当然,有些垃圾回收器(譬如CMS垃圾回收器)出于效率的原因,可能会不进行压缩。
**3)持久代(Perm Gen):**持久代主要存放类定义、字节码和常量等很少会变更的信息。
总结:
-
1、新生代: 新生代中的对象存活率低,只要付出少量的复制成本就能完成回收过程,因此选用复制算法;
-
2、老生代: 老生代中的对象存活率高,并且没有额外空间进行分配担保,因此选用 “标记 - 清理” 或 “标记 - 整理” 算法。
3.3、GC有多少种垃圾回收的算法,都是什么?
最后
这份文档从构建一个键值数据库的关键架构入手,不仅带你建立起全局观,还帮你迅速抓住核心主线。除此之外,还会具体讲解数据结构、线程模型、网络框架、持久化、主从同步和切片集群等,帮你搞懂底层原理。相信这对于所有层次的Redis使用者都是一份非常完美的教程了。
整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断!!!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~*
你的支持,我的动力;祝各位前程似锦,offer不断!!!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-s2jXZBqk-1713616494825)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!