30道“热乎乎”的 JVM 典型题目剖析

编号:石山的建筑笔记

周一至周五上午8:30!精美的技术文章准时交付!

获取优质学习资料,请参阅文章末尾

大家好,我是拍摄专栏《从零开始带你成为JVM实战高手》的作者,该消防队队长的昵称,目前在阿里工作。

这个专栏已经写了一个星期,也是朋友狮山老格公众号推广暴君画面的一周。这真是老朋友推荐的好消息。如果你有时间来杭州,请务必喝两杯^ _ ^

好吧,让我们开始做生意吧。从读者在第一周的反应来看,整体非常好,因为定位是从零开始,我用了很多手绘彩色图片来讲解,这是大家都很喜欢的。

然而,也有许多“老鸟”学生希望尽快加快并尽快到达最好的部分:案例是实际的。但是,我还是想提一下,因为我照顾了很多基础薄弱甚至没有基础学生的JVM学生,我仍然会保持稳定。我希望这些基础学生有权再次复习!

另外,在文章的第一周,每个人的互动也非常活跃。我很高兴看到这些。如果你单独写它,你就不会想到它,效果会大大降低。

下面,我编写了第一周所有学生中最典型的30个问题,并给出了答案。你可以仔细看看并仔细思考。看看你是否对这些问题有疑问。

问题

方法完成后,引用消失,堆内存不必消失。执行报告导出时,许多人不断在for循环中创建对象。很容易导致堆溢出。这个大文件导出怎么会破坏?

答案

建议不要在for中创建对象,可以在外部创建对象,并在for循环中修改对象中的数据。

问题

1. Java支持多线程,每个线程都有自己的Java虚拟机堆栈和本地方法堆栈,是这样的吗?

2.新创建的实例在堆内存中,实例变量也在堆内存中?是这样的吗?

答案

1和2都被正确理解

问题

您好,我不太了解堆叠和弹出的含义。你能解释一下吗?谢谢!

答案

在堆栈上,执行方法时,为此方法创建堆栈框架。

堆叠,就是你的方法已经完成,它会弹出,其实这是没必要担心的,明天的文章会有详细的插图,你会看到。

问题

如果是父类,以下是什么?加载父类 - >加载子类 - >初始化父类 - >初始化子类,加载父类 - >初始化父类 - >加载器类 - >初始化子类

答案

不,加载父类是父类,除非使用子类加载子类;但在加载子类进行初始化之前,必须首先加载父类,初始化父类

问题

类加载器有三层。如果第二层中的类加载器可以加载这些类,则无需上去查找要加载的父类。

由于类只在使用时才加载到内存中,因此必须使用新对象,但是在体验类的所有进程之前是否有必要实例化该类?

答案

没错,你必须首先加载类然后实例化对象

问题

第一课的内容更详细地解释了java程序的执行过程,但我觉得提出的问题在文章中找不到答案。也许这是一个我需要在课后找到答案的问题。仍然希望能有更全面的答案

答案

问的问题是每个人的思考问题。第二天会给出一个简单的解释,但实际上,了解文章的内容,你可以自己找到理解的信息,这是一个小作业,是一个思考的过程

问题

对象头(4个字节)+类指针(4个字节)+字段(参见存储类型),但jvm内存使用量是8的倍数,因此结果应向上舍入为8的倍数

答案

非常好,就是这样。

问题

如果我有一个静态成员变量int,那么多线程更改是否存在线程安全问题,为什么?

答案

内存中的静态成员变量只有一个副本,属于该类。如果同时修改多个线程,则会出现可能导致数据错误的并发问题。

问题

按需加载类加载,是否可以一次加载所有类?

答案

如果它是默认的类加载机制,那么在代码运行时会加载什么类。如果您想自己加载类,则需要编写自己的类加载器

问题

为什么你必须找到第一级类加载器并直接从顶级类加载器中查找它?

答案

事实上,在这个问题上,你不必太担心。每个层加载器加载一个类,将其推送到父类加载器,然后转到顶级类加载器。如果发现无法加载它,请按下子类加载。加载以确保永远不会重复加载类。

至于为什么不直接寻找顶级类加载器,这是因为类加载器本身就是父子关系模型

想想Java代码实现。他的底层子类加载器只能通过他引用的父类加载器找到。如果直接查看顶级类加载器,这是不合适的,那么顶级类加载器不必硬编码?

这是一种代码设计理念,可确保代码的可伸缩性。

问题

在执行新的replicamanager()代码行时是否加载了replicaamanger类?或者是在装载cafka的同时加载?

答案

执行新ReplicaManager时加载类

问题

仍然不明白jvm和平时在机器上运行的系统之间的关系

答案

实际上,它非常简单,您在机器上运行的系统实际上是一个JVM进程,JVM进程将执行系统中编写的代码

问题

类文件在准备阶段分配内存。在准备阶段是否创建了该类的类对象?如果实例变量具有初始值,那么在初始化阶段是否为实例变量分配了类变量?初始化后是否有实例?

答案

该类是在准备阶段分配内存空间的实例变量。在创建类的实例对象时,将初始化类的初始化阶段。它只是初始化类。它与对象无关。 new关键字将构造一个对象。 p>

问题

家长代表团可以解决班级重复加载的问题。根据文章,每个类加载器都有不同的类加载路径。这些类加载路径可以重叠吗?

答案

不同类加载器的路径通常不重叠

问题

自定义类加载器本身由系统加载器加载,这意味着它本身不加密,然后我可以获得反编译的类来查看类文件是否被解密。老师喜欢这个吗?

答案

是的,因此有必要对类文件进行特殊混淆,并且可以使用商业产品

问题

作为Web容器,有必要解决跨应用程序的独立应用程序共享问题。 Tomcat必须支持多级自定义类加载器

答案

非常好的猜测,明天会给出答案

问题

用户应该在希望类准备好一些数据时使用该类。我想jvm设计器首先设计了执行静态代码块的机制。我希望开发人员在这里使用课程之前准备好准备的工作。 p>

为什么类的初始化需要执行静态代码块并将值赋给静态成员变量,因为数据在方法区域?启动类,扩展类和自定义加载器都指定了加载路径,因此重新加载类应该没有问题,因此父级不需要委派。

答案

是的,必须有一个初始化过程,准备类级数据父母以避免重复加载,并在评论区域多次回复此问题,你可以看看

问题

实际上,初始化时间是主动使用类:在调用静态方法时主动使用类的场景,main方法本质上是一个静态方法,没有调用的主方法和没有调用的静态方法!

有一个问题,首先会加载包含main方法的类。如果项目中有多个类使用main方法,是否会加载?

答案

不,你启动一个jar包,你需要指定一个主要的主类,第一个是加载他

问题

Tomcat本身是一个java程序,那么tomcat实现程序的类是由应用程序类加载器加载的,用户自己的java程序war包,进入tomcat程序的类路径

因此用户的程序和tomcat程序由应用程序类加载器加载,该加载器位于jvm中

答案

非常好的回复,文章明天会给出答案

问题

有一个问题,首先会加载包含main方法的类。如果项目中有多个类使用main方法,是否会加载?

答案

当你启动一个jar包时,它将指定main方法所在的类,这是唯一的。

问题

为什么类的初始化需要执行静态代码块并将值赋给静态成员变量,因为数据在方法区域?启动类,扩展类和自定义加载器都指定了加载路径,因此重新加载类应该没有问题,因此父级不需要委派。

答案

这是对的,这个类在方法区域,他在记忆中,所以你必须为他初始化它。分配仍然是必要的。例如,如果启动类加载器,则可以指定类以某种方式加载其他目录,然后必须转到父代理。如果加载这些特殊区域的类,则可以委托给启动类加载器,不要重复加载。

问题

老师,请让班级加载家长委托机制。为什么要首先找到加载的父项而不是自己查找?这个设计有什么好处?

答案

好处是类加载器的每个级别都可以完成其工作,并且不会重复加载类。

例如,如果在代码中使用两个不同级别的类加载器,请尝试加载一个类。如果您有父代委托机制,您将首先找到要加载的父类加载器。如果它被加载,那么它只会加载这个类。

否则,如果没有父代委托机制,那么两个不同级别的类加载器可以加载同一个类,导致重复加载类!

问题

如何实现自定义类加载器?

答案

自己编写一个类,继承ClassLoader类,重写类加载方法,然后使用自己的类加载器将类加载到内存路径下。

问题

看到一个字:动态部署,那么有相应的静态部署吗?如何解释? (谢老师回答)

答案

假设在Tomcat中部署了后台,动态部署也是一个热门部署

是直接系统进入Tomcat对应的目录,他自动将您的最新代码重新加载到您的热部署,不需要停止并重启Tomcat;

否则,首先停止Tomcat,然后将最新代码部署到Tomcat目录,然后重新启动Tomcat

问题

-XX: + TraceClassLoading你可以看到加载了哪些类,并试验它,jre \ lib \ rt.jar下的类都被加载,其他的都是当时加载的。

答案

这是正确的,在明天将要更新的第三篇文章中,我们将解释类加载机制。 rt.jar属于核心类库,属于支持我们的Java系统运行的底层类库,所以它将被加载

我们自己编写的代码通常是代码运行使用的类,以及将加载哪个类

问题

老师,类加载器是一次性加载jar包中的所有类吗?

答案

不,首先加载包含main方法的主类,然后运行你编写的代码,你使用的类,以及要加载的类

问题

通过代码混淆机制,增加反编译后的可读性!或者它可以基于二进制加密,学生从未使用它!

答案

事实上,对于这个一般用于商业产品,有很多第三方公司提供加密产品,百度,类文件加密,你可以看到,直接使用他们的产品

问题

类源文件保护,代码混淆技术可以使用,有很多方法,如老师在答疑区提到的商业加密软件

答案

非常好,就是这样

问题

查看文本内容,它会加载字节码两次,第一次加载到jvm,然后在程序执行时加载。有点疑惑!

答案

你好,没有加载两次,JVM首先将“.class”字节码文件中的类加载到内存中,然后直接执行加载的类geek,它不会被重复加载

问题

该工具可以反编译该类文件。有没有办法加密类文件而不影响它的执行? Windows桌面程序通常打包成dll文件,java中有更好的方法吗?

答案

是的,例如jvmti小工具可以加密类文件

另外,为了保护源代码的安全性,许多商业公司已经引入了专业级的加密产品,可以收费使用。

解密通常可以基于自定义类加载器实现,在加载类时解密类,以便您可以保护源代码安全性。

最后,如果您遵循委托模型的加载过程和实际的实现过程(由读者描绘),请附加两个Tomcat类来加载

4f640443f6274308bae970d6f02e15b2

092da639be7445cfa2c18972e6f912de

这些是本周显示的典型问题。你明白吗?

该专栏刚刚更新了一周,并赢得了同学们的好评。这是我写作的最佳奖励。在这里继续占据众多朋友,给自己一个小广告,厚脸皮贴的截图,谢谢你的支持!

61e9bfd713d94169adfb185416f17623

8deb26043c08495eb28dbfc3f47453e1

6b0f6de8e27e40c0b0d46655de5072f7

ed01f880fc744315a8dbd3ab0c3514cd

a8cfa5292204447cbbe872fd932ec78b

推荐专栏:

《从零开始带你成为JVM实战高手》

作者是我的老朋友,是前一个团队的左臂

在线上经历过各种大型复杂系统的血腥飓风

他目前是Ali的高级技术专家,在JVM的生产实践方面拥有丰富的经验

有关列的列表,请参阅文章的结尾,您可以扫描下面的海报进行试用

bb2f7b9dbeac474080fb37f4d12298a6

通过上面的海报购买,然后返回给你24元

如何获得:添加VX:Giotto1245,密码:现金返还