1.JVM运行流程
首先通过编译把Java代码转换成字节码文件,然后类加载器(ClassLoader)再把字节码文件加载到内存中,放在运行时数据区的方法区内,然后需要特定的命令解析器执行引擎,
将字节码翻译成底层系统指令,再交由CPU去执行.
2.说一下JVM运行时数据区
Java虚拟机在执行Java程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域.
这些区域都有各自的用途,以及创建和销毁的时间.
有些区域随着虚拟机进程的启动而存在,有些区域则是依赖线程的启动和结束而建立和销毁.
Java虚拟机所管理的内存被划分为如下几个区域:
方法区, 虚拟机栈,本地方法栈,堆,程序计数器.
程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,
分支,循环,跳,转,异常处理,线程恢复等基础功能,都需要依赖这个计数器来完成:为什么要线程计数器?因为线程是不具备记忆功能.
Java虚拟机栈(Java Virtual Machine Stacks):每个方法在执行的同时都会在虚拟机栈中创建一个栈帧(Stack Frame) 用于储存局部变量表,操作数栈,动态链接,方法出口等信息;
栈帧就是Java虚拟机栈的下一个单位.
本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务Java方法的,而本地方法栈是为虚拟机调用Native方法服务的;Native关键字修饰的方法
是看不到的,Native方法的源码大部分都是C和C++的代码.
Java堆(Java Heap):Java虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例,都在这里分配内存;
方法区(Method Area):用于储存已被虚拟机加载的类信息,常量,静态变量,即时翻译后的代码等数据.
3.说一说你对Java堆的理解?
Java堆(Java Heap) 是java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例.
在Java虚拟机规范中描述的是:所有的对象实例以及数组都要在堆上分配.
java堆是垃圾收集器管理的主要区域,因此也被称为"GC堆"
4.对Java方法去的理解?
方法区是所有线程共享的内存区域,它用于储存已被Java虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.
5.知道直接内存吗?
直接内存(Direct Memory) 并不是虚拟机运行时数据区的一部分,也不是Java虚拟机中定义的内存区域,
直接内存是基于物理内存和Java虚拟机内存的中间内存.
6.强引用,软引用,弱引用,虚引用的区别?
强引用:我们平时new了一个对象就是强引用,例如 Object obj = new Object() ; 即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象,
软引用:如果对象只具有软引用,则内存空间足够,垃圾回收站就不会回收他;如果内存空间不足了,就会回收这些对象的内存.
SoftReference<String> softRef = new SoftReference<String>(str) ;//软引用
弱引用:具有弱引用的对象拥有更短暂的生命周期,在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间是否足够,都i会
回收它的内存. String str = new String ("abc"); WeakReference<String> abcWeakRef = new WeakReference <String>(str);
虚引用:如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,虚引用主要用来跟踪对象被回收期回收的活动.
7.有没有了解过GC?
GC是垃圾收集的意思
在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,
只有在虚拟机空闲或者当前,堆内存不足时,才会触发执行.
扫描那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收.
8.垃圾回收期的原理是什么?有什么办法手动进行垃圾回收?
对GC来说,当程序员创建对象时,GC就开始监控这些对象的地址,大小以及使用情况.
通常GC采用有向图的方式记录和管理堆(heap) 中的所有对象.
通过这种方式确定哪些对象是"可达的", 哪些对象是"不可达的",当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间,
程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定执行.
9.讲一下新生代,老年代,永久代的区别?
在Java中,堆被划分成两个不同的区域:新生代(Young) 老年代(old)
划分的目的是为了使JVM能够更好的进行内存的分配以及回收,
新生代中一般保存新出现的对象,所以每次垃圾收集时都发现大批对象死去,只有少量对象存活,便采用了复制算法,只需要付出少量存活对象的复制成本,就可以完成收集,
老年代中一般保存存活了很久的对象,他们存活率高,没有额外空间,对它进行分配担保,就必须采用"标记-清理"或者"标记-整理" 算法.
永久代就是JVM的方法区,在这里都是放着一些被虚拟机加载的类信息,静态变量,常量等数据,这个区中的东西比老年代和新生代更不容易回收.
10.对象什么时候可以被垃圾回收站回收?
当对象对当前使用这个对象的应用程序变得不可触及的时候,这个对象就可以被回收了.
垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC)
11.什么是类加载器?
主要有以下四种类加载器:
(1)启动类加载器(Bootstrap ClassLoader)用来加载java核心类库,无法被java程序直接引用
(2)扩展类加载器(extensions class loader) 它用来加载Java的扩展库,Java虚拟机的实现会提供一个扩展库目录,该类加载器再此目录里面查找并加载Java类.
(3)系统类加载器(system class loader) :它根据Java应用的类路径(CLASSPATH) 来加载Java类,一般来说,Java应用的类都是由它来完成加载的,可以通过ClassLoader.getSystemClassLoader()来获取它.
(4)用户自定义类加载器,通过继承java.lang.ClassLoader类的方式实现.
12.说一下类装载的执行过程?
类装载分为一下5个步骤:
加载:根据查找路径找到相应的class文件然后导入;
验证:检查加载的class文件的正确性;
准备:给类中的静态变量分配内存空间;
解析:虚拟机将常量池中的符号引用替换成直接引用的过程;
初始化:对静态变量和静态代码块执行初始化工作;
13.双亲委派
当一个类收到了类加载请求时,不会自己先去加载这个类,而是将其委派给父类,
由父类去加载,如果此时父类不能加载,反馈给子类,由子类去完成类的加载.
14.JVM调优
JDK自带了很多监控工具,都位于JDK的bin目录下,
其中最常用的是jconsole和jvisualvm这两款视图监控工具.
jconsole:用于对JVM中内存,线程和类等进行监控;
jvisualvm:JDK自带的全能分析工具,可以分析:快照内存,线程快照,程序死锁,监控内存的变化,gc变化等.
标签:面试题,Java,对象,虚拟机,回收,内存,JVM,加载 From: https://www.cnblogs.com/carney/p/17072367.html