Java
232 篇笔记
- 6.41 PriorityBlockingQueuehistorical
1. 是什么 底层使用数组(二叉堆)实现的无界的阻塞队列 读读、读写、写写相互阻塞 可以排序 由于无界,所以put操作不会阻塞,但是take操作会阻塞(队列为空的时候) 1.1. 二叉堆 一颗完全二叉树,堆序性质为,每个节点的值都小于其左右子节点的值,二叉堆中最小的值就是根节点。 底层用数组进行存储
- 6.42 SynchronousQueuehistorical
1. 是什么 底层使用单向实现的阻塞队列,不存储元素 一个写者必须同时有一个读者才能进行下去,反之亦然。 否则写者将会一直阻塞或者读者将会一直阻塞 2. 使用 3. 原理 3.1. 构造方法 3.1.1. Transfer 3.1.2. QNode 3.2. put 阻塞 3.2.1. 调用Tran
- 6.43 Atomichistorical
1. 是什么 线程安全的原子类,底层使用CAS实现 2. 使用 以AtomicInteger为例 3. 原理分析 3.1. 构造方法 可以看到主要有三个属性: Unsafe unsafe 、 long valueOffset 和 volatile int value - 关于Unsafe类的解释参考
- 7.2 Java线上问题排查historical
1. 内存占用100% / 内存问题 1.1. 查找Java进程ID top 命令,按下 M 查看哪个java进程占用内存最高 1.2. 分析是否发生OOM OOM问题举例.md 2. CPU占用100% / 线程问题 2.1. 查找Java进程ID和线程ID 1. top 命令,按下 P 查看哪个
- 7.3 1.垃圾回收思想historical
1. 引用计数法 每个对象都有一个计数器,有变量引用时+1,引用失效则-1。当计数器为0的时候则对其进行回收 优点:简单高效 缺点:无法解决循环引用的问题 循环引用是指A对象引用B对象,B对象又引用A对象,但是A,B对象已不被任何其他对象引用 2. 可达性分析 从GC Root出发,通过引用关系遍历
- 7.4 类生命周期historical
1. 类生命周期 主要有加载、连接、初始化、使用、卸载这几个步骤 1.1. 加载 当我们的代码需要使用一个类的时候,这个类不在JVM中的时候就会加载 1.1.1. 由谁加载 由类加载器负责加载类加载器 1.1.1.1. 类加载器分类 - 启动类加载器负责加载JAVA HOME/lib - 扩展类加载
- 7.5 内存分区historical
1. JVM内存分区 1.1. 线程共享 1.1.1. 堆 - 在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。之所以说几乎所有,不是说所有的是因为较新版本的Java(从Java 6的某个更新开始)中,由于JIT编译器的发展和”逃逸分析”技术的逐渐成熟,
- 7.6 调优思路historical
1. 调优的目的 减少Full GC的次数/降低Full GC耗时/降低内存占用 所谓JVM优化,就是尽可能让对象都在新生代里分配和回收,尽量别让太多对象频繁进入老年代,避免频繁对老年代进行垃圾回收,同时给系统充足的内存大小,避免新生代频繁的进行垃圾回收 2. 生产上整体步骤 2.1. 观察应用的G
- 7.7 2.垃圾回收算法historical
1. 标记清除 垃圾回收分成两个阶段 - 标记: 从GC Root出发,标记所有可达的对象。未被标记的就是垃圾对象 - 清除: 清除所有未被标记的对象 1.1. 特点 - 会产生内存碎片(不连续的内存空间), 需要分配较大的对象时,无法找到足够的连续内存空间。 2. 标记整理 分标记和整理阶段。 -