第二部分 CoreJava基础(3)
第06章 JVM相关
6.1 JVM的工作原理
解析:很多大的互联网公司笔试时,会让你画一下JVM的结构图,然后让你解释一下各部分的意义,所以这个面试命中率还是很高的,作为基础扎实的求职者是应该要会的。纠错:搜索引擎--->执行引擎。
参考答案:下面是我画的一个JVM的结构图
1.类装载器子系统: 负责查找并装载Class 文件到内存,最终形成可以被虚拟机直接使用的Java类型。 2.方法区: 在类装载器加载class文件到内存的过程中,虚拟机会提取其中的类型信息,并将这些信息存储到方法区。方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。由于所有线程都共享方法区,因此它们对方法区数据的访问必须被设计为是线程安全的。 3.堆: 存储Java程序创建的类实例。所有线程共享,因此设计程序时也要考虑到多线程访问对象(堆数据)的同步问题。 4.Java栈: Java栈是线程私有的。每当启动一个新线程时,Java虚拟机都会为它分配一个Java栈。Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈或出栈。当线程调用java方法时,虚拟机压入一个新的栈帧到该线程的java栈中。当方法返回时,这个栈帧被从java栈中弹出并抛弃。一个栈帧包含一个java方法的调用状态,它存储有局部变量表、操作栈、动态链接、方法出口等信息。 5.程序计数器: 一个运行中的Java程序,每当启动一个新线程时,都会为这个新线程创建一个自己的PC(程序计数器)寄存器。程序计数器的作用可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Natvie方法,这个计数器值则为空(Undefined)。 6.本地方法栈: 本地方法栈与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。任何本地方法接口都会使用某种本地方法栈。当线程调用Java方法时,虚拟机会创建一个新的栈帧并压入Java栈。然而当它调用的是本地方法时,虚拟机会保持Java栈不变,不再在线程的Java栈中压入新的帧,虚拟机只是简单地动态链接并直接调用指定的本地方法。如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。 7.执行引擎: 负责执行字节码。方法的字节码是由Java虚拟机的指令序列构成的。每一条指令包含一个单字节的操作码,后面跟随0个或多个操作数。执行引擎执行字节码时,首先取得一个操作码,如果操作码有操作数,取得它的操作数。它执行操作码和跟随的操作数规定的动作,然后再取得下一个操作码。这个执行字节码的过程在线程完成前将一直持续。 |
6.2 类的加载机制
解析:这个题目看上去不太容易,但实际上在学习Java第一节课的时候,这些知识老师都已经告诉我们了,第一节课就是安装JDK配置环境变量,PATH,JAVA_HOME大家肯定不默生,但随着IDE的使用,CLASSPATH环境变量被慢慢遗忘了,CLASSPATH就是配置我们自己开发的项目路径,JVM在加载我们写的类时,会根据classpath从左到右各个项目中依次查找是否有这个包,包下是否有这个类,找到类后会验证其中的packeage包的路径是否与参数中的路径一致,是则加载,不是会报NotFoundClassException的异常
参考答案:要了解类的加载机制,首先要了解JVM使用到的类的加载器;这里主要有bootstrap classloader、extension cassLoader、AppClassLoader三个类的加载器,第一个是C++写的,两后两个都是JAVA写的,JVM还给我们开放一个ClassLoader来扩展自己的加载器,当然后两个加载器也是继承了ClassLoader。bootstrap classloader在JVM运行的时候加载java核心API以满足java程序最基本的需要,其中就包括用户定义的ClassLoader, ExtClassLoader是用来加载java的扩展API的,也就是/lib/ext中的类。AppClassLoader是用来加载用户机器上CLASSPATH设置目录中的Class的,通常在没有指定ClassLoader的情况下,程序员自定义的类就由该AppClassLoader来进行加载。 JVM为了避免类的重复加载,引入了委托加载机制,比如A中定义B的引用,对于B的加载是通过委托A的加载器去加载;在上面我们也提到了双亲委托加载机制,APP加载器加载一个类时,首先会调ExtClassLoader, ExtClassLoader会调用 bootstrap classloader如果发现类已经加载就不再加载。 扩展:回答完上面这些应该已经差不多了,求职者可以多关注一下,比如预加载,被动加载等。 |
6.3 GC的工作原理
解析:Java的垃圾回收机制是java语言优越性的一大特色,也奠基它的高级语言的地位。这是一个初级、中级、高级、专家级职位都喜欢面试的问题,因为只有熟练了解JavaGC工作原理,才能写出质量更高的代码,才能更好的在代码级别做性能优化
参考答案:现在市场上JVM的实现厂家很多,不同的厂家对垃圾回收的算法实现也不同,目前主流上常的算法有标记清除、分代、复制、引用记数、增量回收等,而目前最常用的JVM是SUN公司(现被Oracle收购)的HotSport,它采用的算法为分代回收。 HotSport将 jvm中堆空间划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation)。年轻代和年老代是存储动态产生的对象。永久带主要是存储的是java的类信息,包括解析得到的方法、属性、字段等等。永久带基本不参与垃圾回收。我们这里讨论的垃圾回收主要是针对年轻代和年老代。具体如下图(网络提供)
年轻代又分成3个部分,一个eden区和两个相同的survior区。刚开始创建的对象都是放置在eden区的。分成这样3个部分,主要是为了生命周期短的对象尽量留在年轻代。当eden区申请不到空间的时候,进行minorGC,把存活的对象拷贝到survior。年老代主要存放生命周期比较长的对象,比如缓存对象。具体jvm内存回收过程描述如下(可以结合上图): 1、对象在Eden区完成内存分配 2、当Eden区满了,再创建对象,会因为申请不到空间,触发minorGC,进行young(eden+1survivor)区的垃圾回收 3、minorGC时,Eden不能被回收的对象被放入到空的survivor(Eden肯定会被清空),另一个survivor里不能被GC回收的对象也会被放入这个survivor,始终保证一个survivor是空的 4、当做第3步的时候,如果发现survivor满了,则这些对象被copy到old区,或者survivor并没有满,但是有些对象已经足够Old,也被放入Old区 XX:MaxTenuringThreshold 5、当Old区被放满的之后,进行fullGC。 由于fullGC会造成很大的系统资源开销,所以一般情况下通过代码规范和JVM参数设置来减少fullGC的调用,提高性能。 上面只是从算法实现上来说明的,目前主流的垃圾收集器主要有三种:串行收集器、并行收集器、并发收集器。 这里有兴趣的朋友可以查一下,绝对是加分点,如果在串行的垃圾回收器进行fullGC会造成应用的短暂中断,这是一个很危险的事情,所以一定要了解清楚各种实现方式的区别。
|
6.4 Java的反射机制
解析:这个概念定义起来比较简单,但是使用却不容易,现在很多主流的开源框架中DI,IOC的实现很多都是用Java反射机制来做的,可以适当深入研究一下。
参考答案:Java发射机制可以让我们在运行时加载,探知,使用编译期间完全未知的classes。换句话说就是Java程序可以加载一个在运行时才得知名称的class,获悉其完整构造,并生成其对象实体,或对其fields设值,或调用其methods。 反射的作用:在运行的时判定任意一个对象所属的类;运行时,构造任意一个类的对象;运行时,判定一个类所属的成员变量和方法;在运行时调用任意的一个方法;生成动态代理。 反射的实现步骤(不问不需要答),1、获取类的常用方式有三种:a) Class.forName("包名.类名"),最常用、推荐;b) 包名.类名.class最简捷;c) 对象.getClass的方式获得。2、对象的实例化,上面已经获取了类,只需要调用类的实例化方法,类.newInstance()便可。3、获取属性和构造等,可以参考JavaApi的调用,类. getDeclaredFields,类. getConstructor(..)等。
|
6.5 JDK性能分析工具及应用
解析:这里主要针对一定工作经验的人,而且工作经验越久可能问的越详细,主要考察对JDK性能的监控,用以性能调优。
参考答案:JDK性能分析工具很多,像jprofiler及yourkit是性能十分优越,但使用费用也不低,对于开发人员的对性能这块的监控JDK本身就给提供了很多优秀的免费的监控工具,如Visualvm(如果jdk自带版本低,可以单独下载)是一款堪比上面商业性能的监控工具、jconsole(下面是我的一个应用截图)能够监视和管理查看堆内存,线程,类,CPU状况。直接双击就可以启动了,然后选择连接本地local还是远程remote,而且支持控制台管理;jstack 主要用于线程死锁的监控;jmap 主要用于监控内存泄露时候对象占用的字节数;jstat 主要用于监控jvm的gc使用情况;jhat 主要用于分析jmap产生的dump并提供web页面查看分析结果。
|
相关推荐
### 2015Java面试指南知识点概览 #### 一、应聘求职 - **简历篇**:在求职过程中,一份精炼且突出个人优势的简历至关重要。面试者需注意简历的内容应当简洁明了,避免冗长无实质内容的描述,并确保简历中提到的...
为了帮助开发者们在面试中脱颖而出,市面上出现了许多专注于Java面试的指南书籍,其中《Java高分面试指南》以其全面的内容和深入浅出的讲解方式,成为了众多求职者的青睐之作。在这份指南中,不仅覆盖了Java的基础...
「Java面试指南」一份通向理想互联网公司的面试指南,包括 Java基础、Java并发、JVM、MySQL、Redis、Spring、MyBatis、Kafka、计算机操作系统、计算机网络、系统设计、分布式、Java 项目实战等
现在,我们来详细说明本《Java求职面试指南》中的核心知识点: 1. Java基础知识 - “==”与“equals”的区别:前者比较的是两个对象的引用是否相同,即它们是否指向同一个对象的内存地址;而后者比较的是两个对象...
「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识。准备 Java 面试,首选 JavaGuide!「「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识。准备 Java 面试,首选 ...
Java面试指南是为中高级Java开发者准备的一份详尽参考资料,旨在帮助他们在面试过程中展现出扎实的技术功底。这份指南涵盖了Java编程语言的核心概念、高级特性、并发编程、内存管理、性能优化、框架应用等多个关键...
JavaOOP面试题 Java集合/泛型面试题 Java异常面试题 Java中的IO与NIO面试题 Java反射面试题 Java序列化面试题 Java注解面试题 多线程&并发面试题 JVM面试题 Mysql面试题 Redis面试题 Memcached面试题 MongoDB面试题 ...
第一篇(第1章)介绍了求职面试前都需要做好哪些准备工作:如何做好自己的职业规划;掌握面试的流程,在以后的面试中不会感到陌生,消除恐惧;怎样制作一个令人满意、访问量高的简历;去参加面试的时候着装上都需要...
Java程序员面试指南旨在帮助求职者准备Java开发职位的面试,涵盖了广泛的编程概念和技术知识点。这份指南可能包括了从基础语法到高级特性的深入讨论,以及实际编程问题的解决方案。以下是一些可能涵盖的重要知识点:...
Java概论(面试指南)是一本专门针对有一定Java基础的求职者而准备的书籍,目的在于帮助他们梳理和掌握Java面试中的重点知识点。考虑到应聘者的不同水平,从初级到中高级,本书提供了一个实用的复习框架,重点突出,...
从淘宝上买的《JAVA程序员面试指南》电子书清晰版,贡献给大家。
Java最详细的帮你复习面试指南 回顾所有的Java知识 +笔记 +面试指南+简历帮助 全都是干货
这份"2024 Java面试宝典合集"无疑是准备Java求职面试者的宝贵资源。它涵盖了多个关键领域,包括Spring框架、并发编程、Java核心知识以及面试策略等。下面我们将详细探讨这些知识点。 1. **Spring Boot面试题**:...
总的来说,《Java面试宝典2018版》是一本全面而深入的指南,它将帮助Java开发者系统复习技术要点,提升专业素养,从而在面试中展现出色的技术能力。通过深入阅读并实践书中的知识,你将能够更好地应对各种面试挑战,...
2024 Java offer 收割指南java面试题合集分享给需要的同学.pdf
Java面试准备是每位Java程序员在职场跳槽时不可避免的一个环节。在面试中,除了要展示个人的专业技能和项目经验,还需要掌握一些面试技巧来更好地表达自己。以下根据给定文件信息总结出的Java面试准备知识点: 1. ...