面试二:JVM内容

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什么

  1. 执行 system.gc()的时候
    2.老年代空间不足,一次Full GC 之后,然后不足 会触发 java.outofmemoryError:java heap space
    3.永久代空间不足 永生代或者永久代, java.outofMemory PerGen Space
  2. minor之后 survior放不下,放入老年代,老年代也放不下,触发FullGC,
    或者新生代有对象放入老年代,老年代放不下,触发FullGC
    5.新生代晋升为老年代时候,老年代剩余空间低于新生代晋升为老年代的速率,会触发老年代回收
  3. 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的时候,虚引用也会被回收

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值