> 茫茫人海千千万万,感谢这一秒你看到这里。希望我的面试题系列能对你的有所帮助!共勉!
>
> 愿你在未来的日子,保持热爱,奔赴山海!
# 每日三道面试题,成就更好自我
> 昨天既然你有讲到字符串常量池是吧,那这样吧
## 1. 你可以讲下JVM的运行时数据区或者说内存结构吗?
我们可以分为线程私有和线程共享的两种情况
线程私有:程序计数器,本地
方法栈,虚拟机栈
线程共享:堆和
方法区
* 程序计数器:它占用了很小的一块内存空间,记录的是我们当前线程的
一个执行的行数。因为线程它可能不断的切换,如何保证到当前线程时,它执行到哪里呢,就是靠程序计数器来实现的。该内 存区域是唯一
一个 Java 虚拟机规范没有规定任何 OOM 情况的区域。
* 虚拟机栈:当jvm执行
方法时,会在此区域创建栈帧入栈,它存储
方法的各种信息比如局部变量表,操作数栈,动态连接,
方法放回地址这些信息。
* 本地
方法栈:它也虚拟机栈类似,但是它主要为native
方法服务,例如java需要使用c语言的接口服务时。
* 堆: 也叫 Java 堆或者是 GC 堆,它是
一个线程共享的内存区域,也是 JVM 中占用内存最大的一块区域,几乎所有对象都储存
在这里分配内存,也是
垃圾回收期主要的管理区域。
*
方法区:存储一些被虚拟机加载的类信息,常量,静态变量,编译器编译后的
代码等数据。

> 不错不错,JVM都有了解,那再问你一点吧。
## 2. 类加载过程
系统加载Class类型
文件的主要步骤有加载-->连接--> 初始化,连接又可以分为验证-->准备-->解析

* 加载:根据类的全限定名来
获取类的二进制
字节流,在内存中
生成一个代表该类的Class对象
* 验证:主要验证检查class
文件的正确性,比如
文件格式,元数据,字节码,符号引用的验证。
* 准备:主要就是为
类变量分配内存并设置
类变量初始的
一个阶段。
* 解析:虚拟机将常量池内的符号引用替换成直接引用的
一个过程。
* 初始化:它是类加载的最后一步,就是真正执行类中定义的Java程序
代码的过程。
> 可以,那问你最后一道:
## 3. 而其中类加载器是什么,那有哪些呢?
对于任意
一个类,都需要由加载它的类加载器和这个类本身一同确立在 JVM 中的唯一性,每
一个类加载器,都有
一个独立的类
名称空间。而类加载器就是根据指定全限定
名称将 class
文件加载到 JVM 内存,然后再转化为 class 对象。
主要有一下四种类加载器:
* 启动类加载器(BootstrapClassLoader)用来加载java核心类库,无法被java程序直接引用。
* 扩展类加载器(ExtensionClassLoader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供
一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
* 应用程序类加载器(ApplicationClassLoader):它根据 Java 应用的类路径(CLA
sspATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSy
stemClassLoader()来
获取它。一般情况,如果我们没有
自定义类加载器
默认就是用这个加载器。
*
用户自定义类加载器,我们可以自行去通过继承
java.lang.classLoader类的方式实现。

而对于
一个类加载的过程中,如果
一个类加载器收到类加载的请求的时候,它首先不会自己去加载这个类,而是把这个请求委派给自己的
父类加载器去完成,一直到顶层的启动类加载器时,只有当父加载无法完成这一加载请求时,就会往下一层一层的尝试去加载类。这种模式就是双亲委派模式,这中模式的好处可以使类有了层次划分,也保障安全。
> 小伙子不错嘛!今天就到这里,期待你明天的到来,希望能让我继续保持惊喜!
注: 如果
文章有任何
错误和建议,请各位大佬尽情留言!如果这篇
文章对你也有所帮助,希望可爱亲切的您给个三连关注下,非常感谢啦!也可以微信
搜索太子爷哪吒公众号私聊我,感谢各位大佬!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。