java虚拟机全家桶

本文深入探讨Java内存管理机制,包括内存区域如堆、栈、方法区的特性与垃圾回收策略。解析不同引用类型对GC的影响,以及JVM如何执行Minor GC。同时,介绍类加载过程与双亲委派模型。

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

一 内存划分
1 finanlize() 方法工作原理
一个对象被回收要经过2次标记。如果对象没有执行过finalize方法且覆盖了finalize方法,则会进行第一次标记存放到F-Queue队列中;第二次标记是执行finalize()方法时,如果在方法中对象重新与类引用或者方法引用关联上,则可以逃离这次回收。

2 jdk1.8内存分代改进
永久代用元空间来替代

3 java内存划分
在这里插入图片描述

程序计数器: 保存每个线程下一个指令的指针,保证线程切换回来后能接着执行, 不会出现oom
虚拟机栈: 作用于方法层级,为每个线程分配局部变量副本, 存储基础数据类型和引用, 可能出现
stackofoverError oom
本地方法栈:和虚拟机栈类似,只是针对的是native方法
方法区: 永久代,存储类的变量、常量、静态块,可能出现oom
堆:对象存储的地方,gc一般在这里活动,可能出现oom异常,分成新生代和老年代

二 内存溢出
1 分别写出堆溢出和栈溢出的程序
栈溢出:

public void f() {
    f();
}

堆溢出:

public void testd() {
    List<String> list = new ArrayList<>();
    int i = 0;

    while (true) {
        list.add(new String(i + ""));
        i++;
    }
}

三 垃圾回收机制
1 强引用、软引用、弱引用、虚引用的简介,他们和gc的关系?
强引用:最常见的,类似 Object obj = new Object(); 只要引用还存在,gc就不会回收掉引用的对象
软引用:还有用但并非是必要的对象,在系统内存溢出之前,会把这类对象列入到回收范围,进行第二次回收
弱引用:比软引用更弱一层,被弱引用关联的对象只能生存到下一次gc之前
虚引用:最弱的一种引用关系,完全不会对关联对象的生命周期造成影响。目的是对象回收时能收到系统的通知

2 jvm垃圾回收机制,何时出发MinorGC等操作?
eden区无法为一个新对象分配内存时

3 对象如何晋升为老年代
1)大对象直接进入老年代
2)年龄达到阀值也会进入老年代,虚拟机为每个在s区的对象分配一个年龄计数器,每熬过一次gc没被回收,年龄加1,达到年龄上限就会进入老年代
3)s区中相同年龄的对象大小超过了s区的一半以上,则大于等于这个年龄的对象都会进入老年代
4)垃圾回收后,存活的对象大小超过了s区的大小,会把一部分对象担保到老年代中

4 eden区和survivor区的比例分配
jdk1.7是8:1
jdk1.8是6:1

5 垃圾回收算法
标记-清除算法: 最基础的算法,其他算法依据此算法优化
复制算法: 适用于新生代
标记-整理算法:适用于老年代,把存活的对象整理到一端,清除掉边界外的内存
分代整理: 新生代和老年代分别使用适合的算法进行回收

6 System.gc() 和 Runtime.gc() 会做什么事情?
1)java.lang.System.gc()只是java.lang.Runtime.getRuntime().gc()的简写,两者的行为没有任何不同
2)System.gc()和runtime.gc()用于提示jvm进行垃圾回收,但是否立即回收还是延迟回收由java虚拟机决定

四 类加载机制
1 Class.forName()和ClassLoader.loadClass()区别
Class.forName()涉及了类加载过程的:加载、验证、准备、解析、初始化 5个过程
ClassLoader.loadClass()只涉及了类加载过程的加载动作,后面的动作都不会执行

2 什么是类的双亲委派模型
在这里插入图片描述

类加载时,先用父类加载器尝试加载,一层层往上,最后会让启动类加载器尝试加载,能加载就被父类加载器加载了。如果父类加载器不能加载,才会让子类加载器加载。

双亲委派模型的目的: 保证了同一个类只能被同一个类加载器加载

3 类加载过程

加载、验证、准备、解析、初始化
在这里插入图片描述
加载:把class转成二进制字节流
验证:保证字节流是虚拟机需要的,有:文件格式验证、类、方法验证、符号引用验证
准备:类变量设置初始值
解析:把符号引用转成直接引用
初始化:类变量和静态块初始成预期的值

4 描述一下 JVM 加载 Class 文件的原理机制?
JVM中类的加载是有ClassLoader和他的子类来实现的,负责把Class文件加载到内存中。
类加载方式有两种:
1)隐式加载:程序运行时遇到new生成对象时,隐式调用类加载器加载对应的类到jvm中
2)显示加载:通过Class.forName()等方式,显示加载需要的类

 Java类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类(像是基类)完全加载到jvm中,至于其他类,则在需要的时候才加载。这当然就是为了节省内存开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值