1.为什么要用类加载器?类加载是做什么的?怎么加载?
类加载器负责加载 Java 类的字节代码到 Java 虚拟机中
双亲委派模式
2.类的生命周期
加载 验证 准备 解析 初始化 使用 卸载
3.和服务器类加载的区别(tomcat)
1.启动类去加载
2.系统类去加载
3.webapp应用类去加载(class)
4.webapp应用类去加载(lib)
5.通用类加载器去加载
4.双亲委派模式?为什么要用这个模式?
启动类加载器、扩展类加载器、应用程序类加载器、自定义加载器。。
双亲委派模式:
类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,
如果父类加载器可以完成类加载任务,就成功返回;
只有父类加载器无法完成此加载任务时,才自己去加载
防止内存中出现多份同样的字节码
5.java虚拟机的各个部分也存放什么东西
1)程序计数器:几乎不占内存,用于取下一条指令
2)堆:所有通过new创建的对象的内存都在堆中分配,堆被划分为新生代和老年代。
新生代有进一步划分为Eden和Survivor区,最后Survivor由FromSpace和ToSpace组成。
新建的对象都使用新生代分配内存,Eden空间不足,会把存活对象移植到Survivor中。
3)java虚拟机栈:每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧
包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果
4)本地方法栈:用于支持native方法的执行,存储每个native方法调用的状态
5)方法区:存放要加载的类信息、静态变量、常量、属性和方法信息
6.java什么时候gc、gc什么
- 执行 system.gc()的时候
2.老年代空间不足,一次Full GC 之后,然后不足 会触发 java.outofmemoryError:java heap space
3.永久代空间不足 永生代或者永久代, java.outofMemory PerGen Space - minor之后 survior放不下,放入老年代,老年代也放不下,触发FullGC,
或者新生代有对象放入老年代,老年代放不下,触发FullGC
5.新生代晋升为老年代时候,老年代剩余空间低于新生代晋升为老年代的速率,会触发老年代回收 - new 一个大对象,新生代放不下,直接到老年代,空间不够,触发FullGC
7.minor gc/full gc的触发条件
1.超出了作用域或引用计数为空的对象;
2.从gc root开始搜索找不到的对象,而且经过一次标记、清理,仍然没有复活的对象
8.java收集策略
标记-清除算法
标记-整理算法
复制算法
分代收集算法
新生代是用复制算法,minor gc
老年代是用标记-整理算法,Major GC/Full GC
9.oom情况?手写一个oom的代码?工作中怎么解决的
1、堆溢出:不断地创建对象,并且这些对象不会被回收,首先要确认内存中的对象是
否是必要的,也就是要区分出现的是内存泄露(Memory Leak)还是内存溢出(Memory Overflow)
如果是内存泄露,要使用工具查看泄露对象到GC Roots的引用链,找到泄露对象是通过怎样
的路径与GC Roots相关联并导致垃圾收集器无法自动回收它们。
如果不是内存泄露,那么就要检查JVM参数(-Xmx与-Xms)
2、 java栈溢出:如果虚拟机在扩展栈时无法申请足够的内存空间,
则抛出OutOfMemoryError异常
解决办法一个是减少线程数量,若不能减少线程数量,那么考虑“减少内存”的手段来解
决,即通过减少最大堆和减少栈容量来换取更多的线程
3、直接内存溢出:DirectMemory容量默认值与java堆最大值(-Xmx)一样大,也可以通过-XX:MaxDirectMemorySize指定
由DirectMemory导致的内存溢出,可以考虑一下是不是由于程序中使用了NIO导致的,进行排查
public class HeapOOM {
static class OOMObject {
}
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<OOMObject>();
while (true) {
list.add(new OOMObject());
}
}
}
看内存工具:jmap、jconsolne
1.先用top命令,找到cpu占用最高的进程 PID
2.再用ps -mp pid -o THREAD,tid,time 查询进程中,那个线程的cpu占用率高 记住TID
3.jstack 29099 >> xxx.log 打印出该进程下线程日志
4.sz xxx.log 将日志文件下载到本地
5.将查找到的 线程占用最高的 tid 上上上图中 29108 转成16进制 — 71b4
6.打开下载好的 xxx.log 通过 查找方式 找到 对应线程 进行排查
10.java四大引用类型
1.强引用 :强引用关联的对象,永远不会被GC回收。
2.软引用:系统在发生内存溢出前会对这类引用的对象进行回收。
3.弱引用:下一次GC的时候一定会被回收。
4.虚引用:当发生GC的时候,虚引用也会被回收