Java Web技术经验总结(十)

本文主要为《深入理解JVM虚拟机》一书的阅读笔记

  1. Java堆内存溢出:在生产环境中,常常遇到各种Java内存问题,在分析JVM内存时,可以考虑使用MAT。在阅读《深入理解JVM内存》一书时,有如下一个例子:
/**
 * VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError 
 */
public class HeapOOM {
    static class OOMObject {
    }
    public static void main(String[] args) {
        List list = new ArrayList<>();
        while (true) {
            list.add(new OOMObject());
        }
    }
}

在遇到“java.lang.OutOfMemoryError”错误时,首先需要根据MAT工具确认是内存泄漏还是内存溢出。

  1. 关于JVM内存,有几个常用的标志:-Xmn表示年轻代大小;-Xmx表示JVM的最大可用堆内存;-Xms表示JVM的最小可用堆内存;-Xss表示线程栈大小。
  2. 在JVM内存回收中,要识别哪些内存需要回收,一般有两种方法判断某个对象的使用状态:引用计数和可达性分析算法,在JVM中使用“可达性分析算法”进行管理。在Java语言中,可作为GC Roots的对象包括以下几种:
  • 虚拟机栈(栈帧中的本地变量表)中引用的对象;
  • 方法区中类静态属性引用的对象;
  • 方法区中常量引用的对象;
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象;
  1. 关于JVM中的finalize()方法:
  • finalize()方法是对象逃脱死亡的最后一次机会;
  • 一个对象的finalize()方法最多只会被系统自动调用一次;
  • finalize()方法的运行代价高昂,不确定性大,无法保证各个对象的调用顺序。
  • finalize()方法能做的所有工作,使用try-finally或其他方式都可以做得更好、更及时,所以我们最好忘记这个方法的存在;
  1. 垃圾回收算法:标记—清除算法、标记—复制算法、标记—整理算法和分代回收算法,思路是层层递进的,标记—清除算法是基本思路,后续的算法都是为了解决这种基本思路的缺点而发展出来的。
  2. 几种垃圾收集器的选择:(1)在吞吐量优先/CPU资源宝贵的场景下,适合使用Parallel Scanvenge收集器(年轻代) + Parallel Old收集器(老年代)组合;(2)在响应时间敏感的Web服务场景下,适合使用ParalNew(年轻代) + CMS(老年代)组合,在这种情况下还有Serial Old作为CMS出错时的备份;(3)在client模式下的客户端应用场景下,JVM内存不多,串行搜集器效率高、没有多线程开销,适合使用Serial收集器。
  3. 读过的文章:JVM调优总结
  4. 阅读《Java核心技术(二)》的1.5节笔记,Java序列化包括的知识点:(1)ObjectOutputStream和ObjectInputStream连个类的writeObject()/readObject()方法;(2)序列化/反序列化是Java对象与字节流之间的转换过程;(3)序列化生成的文件具备指定的格式,包含了恢复Java对象需要的全部信息;(4)对于不想/不能序列化的字段,使用transient修饰;(5)每个对象都有一个序列号,相同对象的重复会被存储为这个序列号的引用;(6)通过重写readObject/writeObject可以针对某些域进行验证;(7)通过实现Externalizable接口可以完全重写序列化机制;(8)旧代码中的单例设计模式和自己实现的枚举类型,需要实现readResolve()方法,修复bug。

本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。


javaadu

你可能感兴趣的:(Java Web技术经验总结(十))