3、Java内存管理:常见的变量,在内存的不同区域,GC的回收;
-
我在new一个对象的时候,它是被放在内存的那一块区域;
-
成员变量和局部变量:在内存区域位置的区别和回收方面的区别;
相关资料
====
相关文章:Java虚拟机 平行系列二
1、Java内存模型
==========
1.1、JVM整体介绍:
java(javac)–> class文件(JVM把class文件翻译成机器码) --> Linux、Windows等平台(只认识机器码101010)。
JVM可以理解为一个翻译,把class文件翻译成机器码,所以JVM具有跨平台性。
1.2、运行时数据区:
1.3、Java内存模型
内存模型设计:由两个部分的数据非常关键,堆内存和方法区,因为这两个区域的存放的是所有线程共享的数据,因此数据会比较多。而线程私有的数据区如程序计数器,本地方法栈、虚拟机栈里面的数据跟线程的生命周期有关,一旦线程被销毁,这些数据也就被回收了,因此不用过多关注。
2、垃圾回收算法
========
2.1、如何判断某个对象是否是垃圾?
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、简单讲一下新生代和老年代。
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
xLV-1714818510578)]
[外链图片转存中…(img-QNG2ThA4-1714818510578)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!