答:常见的有七大垃圾收集器。首先是Serial收集器,它就是单个垃圾收集线程参与垃圾回收,期间会暂停所有的用户线程,也就是stop the world。新生代采用复制算法,老年代采用标记整理算法。第二个是ParNew收集器,它其实就是Serial收集器的多线程版本,就是多个垃圾收集线程参与垃圾回收,同样的也会暂停所有用户线程。新生代同样采用复制算法,老年代采用标记整理算法。第三个是Parallel Scavenge收集器,它也是多个垃圾收集线程参与垃圾回收,相比于ParNew垃圾收集器它更关注于吞吐量,还有个就是自适应调节策略,就是根据虚拟机收集到的性能监控信息去动态调整这些参数以提供最合适的停顿时间。第四个是SerialOld收集器,它是Serial的老年代版本,也是单个垃圾回收线程参与垃圾回收。第五个是Parallel Old收集器,是Parallel Scavenge收集器的老年代版本。第六个是CMS垃圾收集器,它是标记清除算法的一种实现,它分为4个阶段,初始标记、并发标记、重新标记、并发清除,初始标记是暂停用户线程,标记与GCRoots相连的对象,并发标记是同时开启GC和用户线程,用一个闭包结构去记录可达的对象并进行跟踪。重新标记是暂停所有用户线程,为了修正并发标记期间由于用户线程运行而产生变动的那部分对象。并发清除是开启用户线程,同时GC线程开始对未标记的区域做清扫。第七个是G1垃圾收集器,它默认将堆划分为2048个分区,也是分为4步进行收集,第一步是初始标记,暂停所有用户线程,标记与GCRoots相连的对象,第二步是并发标记,同时开启用户线程和GC线程,用一个闭包结构去保存GCRoots可达的对象并进行跟踪。第三步是最终标记,暂停所有用户线程,去标记那些由于并发标记阶段用户线程运行时所发生变动的那部分对象。第四步是筛选回收,开启用户线程,GC线程开始回收那些未标记的区域。
2、类加载过程?答:类的加载过程分为加载、验证、准备、解析、初始化五个阶段。加载阶段就是通过类的全限定性类名去获取此类的二进制字节流,然后将字节流所代表的静态存储结构转化为方法区的运行时数据结构。 验证阶段就是验证一些文件格式、元数据啥的。准备阶段就是为类变量分配内存并设置初始值的阶段。解析阶段就是将常量池中的符号引用转化为直接引用的过程,也就是得到类或方法在内存中的指针或者偏移量。初始化阶段是执行初始化方法 ()方法的过程,()方法由静态类变量显示赋值代码和静态代码块组成,静态变量显示赋值代码和静态代码块代码从上到下按顺序执行。
3、什么是GCRoots?答:可以作为GCRoots的对象有:在虚拟机栈中引用的对象、类静态属性引用的对象、常量引用的对象、本地方法栈中引用的对象、被同步锁持有的对象。
4、谈谈JVM?答:jvm主要由类加载器、运行时数据区、执行引擎、本地库接口组成。类加载器就是负责把类文件加载到内存的,至于能否运行是交给执行引擎来处理的。运行时数据区分为本地方法栈、虚拟机栈、堆、方法区、程序计数器。本地方法栈就是执行的是本地方法也就是native修饰的方法。虚拟机栈是线程私有的,每个方法被执行的时候都会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。堆的话分为新生代和老年代,比例为1:2,新生代又分为伊甸园区、from区和to区(又叫survivor0区和survivor1区)。伊甸园区和from区、to区比例为8:1:1。是线程共享的一个区域,主要存放一些对象实例。方法区也是线程共享的,主要存放一些常量、类信息、静态变量。程序计数器是线程私有的,就是存放程序将要执行的指令,它是唯一一个不会发生OOM情况的区域。还有就是一些jvm参数,分为标配参数、X参数和XX参数,标配参数就是java -version,java -help等,x参数的话我只是做过了解,平时用的也不多,而XX参数的话是很常用的,比如-Xms和-Xmx,-Xms是设置初始堆内存大小的,默认为本地物理内存的1/64,-Xmx是设置最大堆内存大小的,默认为本地物理内存的1/4,还有很多其他jvm调优参数,例如-XX:printGCdetails它是打印GC垃圾回收详细信息的,还有-XX:newRatio可以设置新生代和老年代的占比,原来不是1:2,如果newratio值为4,那么新生代老年代比例就为1:4,还有的参数就是survivoratio可以设置伊甸园区的占比,原来是8:1:1,可以设置成4:1:1。
5、强引用、软引用、弱引用、虚引用分别是什么?答:强引用就是常见的new对象,垃圾收集器永远不会回收这类型对象。软引用就是如果内存够用就不回收,不够用就回收。弱引用就是不管内存够不够用都会回收。虚引用只是为了在这个对象被收集器回收时收到一个系统通知。
6、类加载器有几种?什么是双亲委派机制?答:类加载器有四种。分别是启动类加载器、扩展类加载器、应用程序类加载器和自定义类加载器。双亲委派机制就是当一个类加载器收到了类加载请求时,它首先不会去加载这个类而是交给它的父类加载器去处理,最终就交给了启动类加载器。当父类加载器都加载不了的时候才会尝试让子类加载器去进行加载。作用是防止加载同一个.class。通过委托去询问上级是否已经加载过该.class,如果加载过了,则不需要重新加载。保证了数据安全。
7、四大垃圾回收算法?答:引用计数法、复制算法、标记清除、标记整理。引用计数法就是在对象中添加一个引用计数器,每当有一个地方引用它,计数器就加一,不引用时,计数器就减一。没被引用到的对象就会被回收。复制算法用于新生代,首先第一次当伊甸园区对象满了以后会触发第一次GC,将存活的对象全部复制到from区,然后清空伊甸园区。当第二次伊甸园区满了以后,会触发第二次GC,这时会对伊甸园区和from区两个区进行扫描,将伊甸园区和from区存活的对象复制到to区并将对象年龄+1。清空伊甸园区和from区,将from区和to区交换,上次的to区就成为下一次的from区,上次的from区成为下次的to区。当对象年龄大于15时就移入老年代,不会产生内存碎片。标记清除算法用于老年代,先标记再清除,标记与GCRoots相连的对象,然后将未标记的区域清除,缺点是容易产生内存碎片。标记整理算法也是用于老年代,先标记与GCRoots相连的对象,然后按照内存地址依次排列,不产生内存碎片。



