JVM系列-第3章-运行时数据区
此章把运行时数据区里比较少的地方讲一下。虚拟机栈,堆,方法区这些地方后续再讲。
运行时数据区概述及线程前言本节主要讲的是运行时数据区,也就是下图这部分,它是在类加载完成后的阶段
当我们通过前面的:类的加载 –> 验证 –> 准备 –> 解析 –> 初始化,这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到我们运行时数据区
类比一下也就是大厨做饭,我们把大厨后面的东西(切好的菜,刀,调料),比作是运行时数据区。而厨师可以类比于执行引擎,将通过准备的东西进行制作成精美的菜品。
运行时数据区结构运行时数据区与内存
内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。不同的JVM对于内存的划分方式和管理机制存在着部分差异。结合JVM虚拟机规范,来探讨一下经典的JVM内存布局。
我们通过磁盘或者网络IO得到的数据,都需要先加载到内存中,然后CPU从内存中获取数据进行读取,也就是说内存充当了 ...
JVM系列-第2章-类加载子系统
第2章-类加载子系统内存结构概述简图
详细图英文版
中文版
注意:方法区只有HotSpot虚拟机有,J9,JRockit都没有
如果自己想手写一个Java虚拟机的话,主要考虑哪些结构呢?
类加载器
执行引擎
类加载器子系统类加载器子系统作用:
类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识。
ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。
加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)
类加载器ClassLoader角色
class file(在下图中就是Car.class文件)存在于本地硬盘上,可以理解为设计师画在纸上的模板,而最终这个模板在执行的时候是要加载到JVM当中来根据这个文件实例化出n个一模一样的实例。
class file加载到JVM中,被称为DNA元数据模板(在下图中就是内存中的Car ...
JVM系列-第1章-JVM与Java体系结构
1、本系列博客,主要是面向Java8的虚拟机。如有特殊说明,会进行标注。
2、本系列博客主要参考尚硅谷的JVM视频教程,整理不易,所以图片打上了一些水印,还请读者见谅。后续可能会加上一些补充的东西。
3、尚硅谷的有些视频还不错(PS:不是广告,毕竟看了人家比较好的教程,得给人家打个call)
4、转载请注明出处,多谢~,希望大家一起能维护一个良好的开源环境。
第1章-JVM和Java体系架构前言你是否也遇到过这些问题?
运行着的线上系统突然卡死,系统无法访问,甚至直接OOM!
想解决线上JVM GC问题,但却无从下手。
新项目上线,对各种JVM参数设置一脸茫然,直接默认吧然后就JJ了。
每次面试之前都要重新背一遍JVM的一些原理概念性的东西,然而面试官却经常问你在实际项目中如何调优VM参数,如何解决GC、OOM等问题,一脸懵逼。
大部分Java开发人员,除了会在项目中使用到与Java平台相关的各种高精尖技术,对于Java技术的核心Java虚拟机了解甚少。
开发人员如何看待上层框架
一些有一定工作经验的开发人员,打心眼儿里觉得SSM、微服务等上层技术才是重点,基础技术并不重要 ...
Java并发体系-第四阶段-AQS源码解读-[1]
可重入锁12345678910111213141516171819202122232425262728293031323334/** * @Author: youthlql-吕 * @Date: 2020/10/22 21:12 * <p> * 可重入锁: * 1、可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁,这样的锁就叫做可重入锁。 * 2、是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提,锁对象得是同一个 * 对象),不会因为之前已经获取过还没释放而阻塞 */public class ReEnterLockDemo { static Object objectLockA = new Object(); public static void m1(){ new Thread(() -> { synchronized (objectLockA){ System.out.println(Thr ...
Java并发体系-第三阶段-JUC并发包-[2]
Phaser工具简介java7中引入了一种新的可重复使用的同步屏障,称为移相器Phaser。Phaser拥有与CyclicBarrier和CountDownLatch类似的功能.
但是这个类提供了更加灵活的应用。CountDownLatch和CyclicBarrier都是只适用于固定数量的参与者。移相器适用于可变数目的屏障,在这个意义上,可以在任何时间注册新的参与者。并且在抵达屏障是可以注销已经注册的参与者。因此,注册到同步移相器的参与者的数目可能会随着时间的推移而变化。
如CyclicBarrier一样,移相器可以重复使用,这意味着当前参与者到达移相器后,可以再一次注册自己并等待另一次到达.
移相器的另一个重要特征是:移相器可能是分层的,这允许你以树形结构来安排移相器以减少竞争
简单例子:
12345678910111213141516171819202122232425262728293031323334353637383940414243/** * @Author: youthlql-吕 * @Date: 2020/10/11 21:57 * <p> * 功能描述: ...
Java并发体系-第三阶段-JUC并发包-[1]
AtomicXXXFieldUpdater
算是一个小补充
简介12345678910111213141516171819public class AtomicIntegerFieldUpdaterTest { public static void main(String[] args) { AtomicIntegerFieldUpdater<Test> updater = AtomicIntegerFieldUpdater.newUpdater(Test.class, "value"); Test ts = new Test(); IntStream.rangeClosed(0, 2).forEach(item -> { new Thread(() -> { int value = updater.getAndIncrement(ts); System. ...
Java并发体系-第二阶段-锁与同步-[3]
synchronized保证三大特性synchronized保证原子性的原理
对num++;增加同步代码块后,保证同一时间只有一个线程操作num++;。就不会出现安全问题。
synchronized保证可见性的原理
synchronized保证可见性的原理,执行synchronized时,会对应lock原子操作会刷新工作内存中共享变 量的值。
synchronized保证有序性的原理
我们加synchronized后,依然会发生重排序,只不过我们有同步 代码块,可以保证只有一个线程执行同步代码中的代码。保证有序性。
synchronized的特性可重入特性意思就是一个线程可以多次执行synchronized,重复获取同一把锁。
12345678910111213141516171819202122232425262728293031/* 目标:演示synchronized可重入 1.自定义一个线程类 2.在线程类的run方法中使用嵌套的同步代码块 3.使用两个线程来执行 */public class Demo01 { pu ...
Java并发体系-第二阶段-锁与同步-[2]
可见性设计的硬件
从硬件的级别来考虑一下可见性的问题
1、第一个可见性的场景:每个处理器都有自己的寄存器(register),所以多个处理器各自运行一个线程的时候,可能导致某个变量给放到寄存器里去,接着就会导致各个线程没法看到其他处理器寄存器里的变量的值修改了,就有可能在寄存器的级别,导致变量副本的更新,无法让其他处理器看到。
2、第二个可见性的场景:然后一个处理器运行的线程对变量的写操作都是针对写缓冲来的(store buffer)并不是直接更新主内存,所以很可能导致一个线程更新了变量,但是仅仅是在写缓冲区里罢了,没有更新到主内存里去。这个时候,其他处理器的线程是没法读到他的写缓冲区的变量值的,所以此时就是会有可见性的问题。
3、第三个可见性的场景:然后即使这个时候一个处理器的线程更新了写缓冲区之后,将更新同步到了自己的高速缓存里(cache,或者是主内存),然后还把这个更新通知给了其他的处理器,但是其他处理器可能就是把这个更新放到无效队列里去,没有更新他的高速缓存。此时其他处理器的线程从高速缓存里读数据的时候,读到的还是过时的旧值。【处理器是优先从自己的高速缓存里取读取变量副本 ...
Java并发体系-第二阶段-锁与同步-[1]
本阶段文章讲的略微深入,一些基础性问题不会讲解,如有基础性问题不懂,可自行查看我前面的文章,或者自行学习。
本篇文章比较适合校招和社招的面试,笔者在2020年面试的过程中,也确实被问到了下面的一些问题。
并发编程中的三个问题
由于这个东西,和这篇文章比较配。所以虽然在第一阶段写过了,这里再回顾一遍。
可见性可见性概念可见性(Visibility):是指一个线程对共享变量进行修改,另一个线程立即得到修改后的新值。
可见性演示12345678910111213141516171819202122232425262728293031323334353637/* 笔记 * 1.当没有加Volatile的时候,while循环会一直在里面循环转圈 * 2.当加了之后Volatile,由于可见性,一旦num改了之后,就会通知其他线程 * 3.还有注意不能用if,if不会重新拉回来再判断一次。(也叫做虚假唤醒) * 4.案例演示:一个线程对共享变量的修改,另一个线程不能立即得到新值 * */public class Video04_01 { public static voi ...
Java并发体系-第一阶段-多线程基础知识
程序、进程、线程的理解1、程序(programm)概念:是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码。
2、进程(process)概念:程序的一次执行过程,或是正在运行的一个程序。说明:进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域
3、线程(thread)概念:进程可进一步细化为线程,是一个程序内部的一条执行路径。说明:线程作为CPU调度和执行的单位,每个线程拥独立的运行栈和程序计数器(pc),线程切换的开销小。
补充:
进程可以细化为多个线程。每个线程,拥有自己独立的:栈、程序计数器多个线程,共享同一个进程中的结构:方法区、堆。
并行与并发单核CPU与多核CPU的理解
单核CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务。例如:虽然有多车道,但是收费站只有一个工作人员在收费,只有收了费才能通过,那么CPU就好比收费人员。如果某个人不想交钱,那么收费人员可以把他“挂起”(晾着他,等他想通了,准备好了钱,再去收费。)但是因为CPU时间单元特别短,因此感觉不出来。
如果是多核的话,才能更好的发挥多线程的效 ...