为什么1.8之后要废弃永久代?
1、实际使用中容易出问题(内存不足或者内存泄漏)
原因:字符串存在永久代中,容易出现性能问题和内存溢出
类及方法的信息比较难确定大小,因此永久大内存大小无法指定,太小容易出现永久代溢出,太大同意导致老年代溢出
2、永久代为GC带来不必要的复杂度,并且回收效率偏低
3、Oracle可能为将HotSpot 与 JRockit 合二为一
Java内存堆和栈的区别?
1、栈内存用来存储基本类型和对象的引用变量,而堆内存时用来存储对象
2、栈内存归属于单个线程,而堆内存中的对象属于所有线程可见,可被所有的线程访问
3、栈内存不足会抛 栈深度溢出 异常,而堆内存时抛 内存溢出 异常
4、栈内存小于堆内存,-Xss 设置栈内存 -Xms设置堆开始大小
Java内存布局
1、对象头
运行时数据:哈希码、GC分代年龄、锁状态标志、线程持有的锁等
类型指针:对象指向类元数据的指针
2、实例数据
3、对齐填充
OutOfMemoryError异常情况
1、Java堆溢出:不断创建对象
2、虚拟机栈和本地方法栈溢出:递归深度太大
3、方法区和运行时常量池溢出( 1.8以后就变成元数据区内存溢出 ):
方法区:不断加载class
运行时常量池:不断生成String
4、本机直接内存溢出:申请很大的内存
如何出现OOM,如何排错:
1、控制台看错误日志
2、使用JDK自带的jvisualvm工具查看系统的堆栈日志
3、定位出内存溢出的空间:堆、栈还是永久代(1.8以后无永久代溢出)
如果是堆溢出,看是否创建了超大的对象
如果是栈溢出,看是否创建了大对象,或者是否产生死循环
Java会出现内存泄漏吗?
理论上有GC机制不会出现,但是实际开发中会出现无用但可达的对象,GC回收也会发现泄漏,例如:
1、Hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器不会回收这些对象
2、使用Netty的堆外ByteBuf 对象,使用完未归还
方法区是否能被回收?
方法区可以被回收,但是价值很低,主要是回收废弃的常量和无用的类。
如何判断无用的类,满足下列三个条件:
1、该类的所有实例都被回收
2、加载此类的ClassLoader已被回收
3、该类对应的Class对象没有在任何地方被引用,无法在任何地方利用反射访问该类
为什么要有那么多不同的引用类型?
Java不同与C可以控制内存的申请和释放,Java需要适当的控制对象被回收的时机,因此需要不同的类型。不同的引用类型其实对GC机制不可控的妥协。例如:
1、利用软引用和弱引用解决OOM问题:用一个 HashMap 来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM 会自动回收这些缓存图片对象所占用的空间,从而有效地避免了 OOM 的问题.
2、通过软引用实现 Java 对象的高速缓存。比如我们创建了一 Person 的类,如果每次需要查询一个人的信息,哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这将引起大量Person 对象的消耗,并且由于这些对象的生命周期相对较短,会引起多次 GC 影响性能
什么是安全点?
SafePoint就是指一些特定的位置,当线程运行到这些位置时,线程的一些状态可以被确定,从而确定GC Root信息,使JVM可以安全的进行一些操作,比如开始GC
SafePoint指的特定位置:
1、循环的末尾
2、方法返回前
3、调用方法的call之后
4、抛出异常的位置
安全域:是指一段代码片中,引用关系不会发生变化,在这个区域任何地方GC都是安全的,安全区域可以看做是安全点的一个扩展。
1、线程执行到安全区域代码是,首先标识自己进入了安全区域,这样GC时就不管进入安全区域的线程了
2、线程要离开安全区时就检查JVM是否完成了GC Roots枚举(或整个GC过程),如果完成就继续执行,如果没有就等待直到收到可以安全离开的信号
收集器 | 串行、并行or并发 | 新生代/老年代 | 算法 | 目标 | 适用场景 |
---|---|---|---|---|---|
Serial | 串行 | 新生代 | 复制算法 | 响应速度优先 | 单CPU环境下的Client模式 |
Serial Old | 串行 | 老年代 | 标记-整理 | 响应速度优先 | 单CPU环境下的Client模式、CMS的后备预案 |
ParNew | 并行 | 新生代 | 复制算法 | 响应速度优先 | 多CPU环境时在Server模式下与CMS配合 |
Parallel Scavenge | 并行 | 新生代 | 复制算法 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
Parallel Old | 并行 | 老年代 | 标记-整理 | 吞吐量优先 | 在后台运算而不需要太多交互的任务 |
CMS | 并发 | 老年代 | 标记-清除 | 响应速度优先 | 集中在互联网站或B/S系统服务端上的Java应用 |
G1 | 并发 | both | 标记-整理+复制算法 | 响应速度优先 | 面向服务端应用,将来替换CMS |