JVM垃圾回收

如何判断对象是否存活垃圾收集器在对堆进行回收前,首先就是需要确定哪些对象还”存活”,哪些已经”死去”(即不可能再被任何途径使用的对象),大致上来说有两种算法: 1)引用计数算法 这也是很多教科书中判断对象是否存活的算法: 给对象添加一个引用计数器,当该对象被引用时,计数器加1;当引用失效时,计数器减1,任何时刻计数器为0的对象就是不可能再被使用的。该算法实现...

阅读全文

类加载与双亲委派模型

前言Java 虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这个过程称作类加载机制。 与那些在编译时进行连接的语言不同,Java 类型的加载、连接和初始化都是在程序运行期间完成的。这种设计虽然会带来一些额外的性能开销,但也为 Java 提供了高度的灵活性——类加载器 +...

阅读全文

JVM运行时区域

JVM运行时内存区域我们以HotSpot虚拟机为前提下展开,因为目前使用最多的还是HotSpot虚拟机。 Java虚拟机在执行Java程序时,会将分配给JVM的内存划分为几个不同的区域。有些区域在JVM启动之后就存在,直到关闭JVM进程;有些区域则依赖于用户线程,随着用户线程的生命周期一同创建和销毁。 从Java1.8开始,JVM内存区域划分如图所示,从图中...

阅读全文

线程池的基本原理

什么是线程池线程池其实是一种池化的技术的实现,池化技术的核心思想其实就是实现资源的一个复用,避免资源的重复创建和销毁带来的性能开销。在线程池中,线程池可以管理一堆线程,让线程执行完任务之后不会进行销毁,而是继续去处理其它线程已经提交的任务。 使用线程池的好处: 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 提高响应速度。当任务到达时...

阅读全文

AQS及其应用

前言在 Java 并发编程中,锁和同步器是不可或缺的工具。从 synchronized 到 ReentrantLock,从 CountDownLatch 到 Semaphore,这些工具的背后都有一个共同的基石——AbstractQueuedSynchronizer(AQS)。 AQS 是 java.util.concurrent 包的灵魂,它提供了一套框架...

阅读全文

ThreadLocal

ThreadLocal概念ThreadLocal,即线程变量,是以一个ThreadLocal对象为key、任意对象为值的存储结构。这个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值。 ThreadLocal使用场景场景1,ThreadLocal 用作保存每个线程独享的对象,为每个线程都创建一个副本,这...

阅读全文

Synchronized的实现原理

概念及用法在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁。但是,随着JDK的升级迭代,对其进行了各种优化之后,有些情况下它就并不那么重了。 先来看下利用Synchronized实现同步的基础:Java中的每一个对象都可以作为锁。具体表现有三种使用方式: 对于普通同步方法,锁是当前实例对象。 对于静态同步方法,锁是当前...

阅读全文

JMM内存模型与volatile关键字

前言CPU Cache模型在现在的计算机中,所有的运算操作都是由CPU的寄存器完成的,而过程涉及数据的存取都需要主存内存的确认。但是主内存由于制造工艺和成本的限制,在访问速度上还是大大落后于不断发展的CPU的处理速度,他们的差距能够达到成千上万倍。于是,就有了在CPU和主内存之间增加缓存的设计。程序在运行的过程中,会将运算所需要的数据从主存复制一份到CPU ...

阅读全文

ConcurrentHashMap源码解析

前言当我们碰到线程不安全场景下,需要使用 Map 的时候,我们第一个想到的 API 估计就是 ConcurrentHashMap,ConcurrentHashMap 内部封装了锁和各种数据结构来保证访问 Map 是线程安全的,接下来我们一一来看下,和 HashMap 相比,多了哪些数据结构,又是如何保证线程安全的。 类注释我们从类注释上大概可以得到如下信息:...

阅读全文

HashMap源码解析

整体架构HashMap 底层的数据结构主要是:数组 + 链表 + 红黑树。其中当链表的长度大于等于 8 时,链表会转化成红黑树,当红黑树的大小小于等于 6 时,红黑树会转化成链表,整体的数据结构如下: 图中左边竖着的是 HashMap 的数组结构,数组的元素可能是单个 Node,也可能是个链表,也可能是个红黑树,比如数组下标索引为 2 的位置就是一个链表,...

阅读全文