• 【无标题】


    题目 01 请你用自己的语言介绍 Java 运行时数据区(内存区域)

    01.堆、虚拟机栈、本地方法栈、方法区(永久代、元空间)、运行时常量池(字符串常量池)、直接内存

    a.堆:
    占用区域最大(占地盘的王者)
    垃圾回收的主要内存区域(垃圾收集器的主要治理对象)
    JDK各版本不断迭代区域划分,只为了更好更快地回收管理此区域
    各线程公用空间(对比虚拟机栈)
    
    • 1
    • 2
    • 3
    • 4
    b.虚拟机栈:
    线程私有空间(从线程出生到死亡一直相伴)——生命周期相同
    其大小决定了方法调用深度,报错的时候打的e.printstack就能看到层层调用。
    StackOverFlow——标识栈内存设置小了,或者死循环了
    那虚拟机栈里面在入栈出栈存的是什么东西呢——栈帧(
    	栈帧:1.调用新方法,栈帧随之创建(方法在虚拟机帧中出入的通关文牒)
    	      2.存储了方法的局部变量表,操作数栈,动态连接和方法返回地址等(方法执行时所有的必备信息)
    	      3.当前栈帧(当前方法——当前类)(执行引擎的操作对象)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    c.本地方法栈:
    	与虚拟机栈的唯一区别就是服务对象不同
    	服务对象:虚拟机栈————为java服务(字节码服务)做服务
    			 本地方法栈————为native方法(比如c++方法)做服务
    
    • 1
    • 2
    • 3
    d.方法区
    	方法区是一个概念区,其具体实现有:永久代,元空间。(类比于降温这个概念的具体实现有:吹风扇和吹空调)
    	方法区要存储:1.class   2.运行时常量池    3.JIT编译器编译之后的代码缓存
    
    • 1
    • 2
    永久代元空间比较
    应用时间JDK1.8以前JDK1.8以后元空间逐步替代永久代
    存储区域存储区域是JVM内存所占用区域物理内存区域占用jvm内存管理空间就得让jvm操心内存移除和垃圾回收的事情
    存储内容方法区需要存的都存只存类的元信息,静态变量和运行时常量池交给堆来存
    e.运行时常量池(字符串常量池)
    class常量池运行时常量池字符串常量池
    范围情况一个class文件只有一个class常量池一个class对象有一个运行时常量池全局只有一个字符串常量池
    存储内容字面量和符号引用字面量和符号引用双引号引起来的字符串
    一个叫dog的class文件有一个自己的**class常量池**。
    如果实例化了两个对象:dog1和dog2,则dog1和dog2各有自己的**运行时常量池**;
    但是不管有多少个对象和文件,全局也是只有一个**字符串常量池**。
    
    • 1
    • 2
    • 3
    f.程序计数器
    从别的线程切换回来,程序计数器告诉你上回执行到哪了。(指路小天才)
    
    • 1
    g.直接内存
    直接内存堆内存
    申请空间耗费性能耗费更高的性能性能耗费更低
    IO读写性能更优对比直接内存差一些
    使用场景有很大的数据需要存储(生命周期长);频繁的IO操作(网络并发场景)数据不是很大

    01.为什么堆内存要分年轻代和老年代?

    就像是收拾街道的清洁工师傅,会把所负责的区域分成两块;
    一块区域(年轻代)经常清理,然后把瓶子和纸盒收起来放到另一块区域(老年代);
    然后年轻代经常清理,老年代隔一段时间清理一次(把瓶子和纸盒卖了)。
    
    • 1
    • 2
    • 3

    题目 02 描述一个 Java 对象的生命周期

    解释一个对象的创建过程

    new指令->>想准备买一口新锅,来专门来炒肉吃
    常量池检查->>看看自己家里是不是买过这样的锅
    是否已加载->>不过是新锅还是旧锅都要拿到厨放这个空间来(已经拿过来就不用拿了)
    分配内存空间->>确保厨放有空间能放下这口锅
    内存空间初始化为零值->>把灶台清理出来准备放锅
    必要信息设置->>在锅盖上标记一下这个锅的用途
    执行init方法->>对这个锅进行涂油开锅
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    解释一个对象的内存分配

    就像是一个人(对象),来到旅店,要住宿,住进一个房间(内存分配)。
    A旅店(Serial,ParNew)的房间是从头到尾进行分配的(内存空间连续),接着上个旅客入住的房子安排(指针碰撞)。
    B旅店(CMS收集器和Mark-Sweep收集器)分配房间内存不连续,会维持一个空闲列表,来从中给旅客来分配空间(空闲列表)
    
    • 1
    • 2
    • 3

    解释一个对象的销毁过程

    类比于黑帮清理门户,如果能和帮派中的常驻长老(类静态属性引用的对象)建立引用联系的(能为他们所用的),就不能当做清理对象,否则会被当做清理对象。当然在清理之前,会垃圾一个机会,如果垃圾能通过调用finlize方法,亮出免死腰牌证明自己是长老的人,则可以免除一死。否则第二次机会,还是被标记为垃圾,必死无疑。

    Step1:先确定垃圾
    一个对象,如果对于其他人没有用处(引用法)会被认定为垃圾。
    一个对象,如果没有在Gcroots对象对象的可触达链路内,则会被认定为垃圾。
    
    可做GcRoots的对象:
    	1.虚拟机栈中,栈帧的本地变量表引用的对象
    	2.方法区中,类静态属性引用的对象
    	3.方法区中,常量引用的对象
    	4.本地方法栈中,JNI引用的对象
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    Step2:给垃圾机会
    第一次被标记为垃圾之后,如果此对象有必要执行finalize方法.
    在执行finalize方法后,还没有与引用链建立联系的会被第二次标记
    
    • 1
    • 2
    Step3:第二次被标记的对象就是真的要回收

    对象的 2 种访问方式是什么?

    类似于作坊(JAVA栈,本地变量表)通过中介找劳工
    
    • 1
    通过句柄访问对象:
    劳工的类型信息和具体劳工的地址信息由中介(句柄)来做保存。不管劳工怎么移动,作坊只要寻找句柄就可以了。
    
    • 1
    通过直接指针访问对象:
    类似于作坊(JAVA栈,本地变量表)自己维护劳工的地址信息,劳工维护自己的类型信息。劳工移动,作坊的引用信息也要做更新。
    
    • 1

    为什么需要内存担保?

    当年轻代通过自身的minoreGc,移动survivor区域都无法有足够空间来放入要加入的新对象时。
    老年代会挺身而出,收留那希望在gc之后还存活的年轻代对象,以留出足够大的年轻代空间来收留新的对象。
    
    • 1
    • 2

    垃圾收集算法有哪些?垃圾收集器有哪些?他们的特点是什么?

    新生代使用算法老年代使用算法特点
    ParNew 收集器并行复制算法,暂停所有用户线程串行标记整理算法,暂停所有用户线程存在线程交互开销(单cpu性能不如Serial)
    ParallelScavenge 收集器并行复制算法,暂停所有用户线程串行标记整理算法,暂停所有用户线程吞吐量优先
    ParallelOld 收集器并行复制算法,暂停所有用户线程并行标记整理算法,暂停所有用户线程ParallelScavenge的老年代版本
    CMS 收集器无(CMS是专门的老年代收集器)并发回收,标记清楚低延迟,会产生内存碎片,对CPU资源敏感
    G1收集器取消老年代年轻代的物理划分取消老年代年轻代的物理划分空间整合:标记整理,局部使用复制算法,但不会产生内存碎片。可预测的停顿
  • 相关阅读:
    C2_W3_Assignment_吴恩达_中英_Pytorch
    Epuck2机器人固件更新及IP查询
    服务器实现端口转发的N种方式
    Edge浏览器如何简单用上ChatGPT
    Vue常见问题
    【论文笔记】基于深度学习的机器人抓取虚拟仿真实验教学系统
    电脑重装系统Win11内核隔离无法打开怎么解决?
    GUI编程--PyQt5--QDiaglog
    linux系统shell脚本开发之循环的使用
    使用kettle采集excel表格中的数据
  • 原文地址:https://blog.csdn.net/ZWB626/article/details/126680281