尚硅谷阳哥JVM笔记
JVM体系结构

类加载器(快递员):
- 只负责加载java文件,编译后的class文件在文件开头有特定的文件表示,将class文件字节码内容从硬盘加载到JVM内存中并将这些内容转换成方法区的运行时数据结构,至于是否可以正常运行由Execution Engine决定。加载class后为模板Class,该模板存放类的结构信息,一个模板可以实例化多个实例
3个classLoader:启动加载器
Bootstrap(C++),扩展加载器Extension(Java),应用程序类加载器AppClassLoader, 分别是祖父孙, 他们都是抽象类,需要被继承。还有用户自定义加载器Java.lang.ClassLoader的子类,用户可以定制类的加载方式, 通过继承ClassLoader类new Object().getClass().getClassLoader()为Bootstrap,是Java祖宗级,在java里输出为nullnew MyObject().getClass().getClassLoader(),即自己new的类,它的加载器是AppClassLoader , 父加载器为Extension- classLoader双亲委派机制:当收到某个java文件的类加载请求,即所有请求都会传送到启动加载类,首先从根加载器(Bootstrap)开始向下寻找,找不到抛ClassNotFound异常,保证了沙箱安全
- 沙箱安全机制:由双亲委派机制实现,只加载从Bootstrap向下找到的第一个文件,保证Java的源码不被污染,
- 程序编译时,加载顺序:静态代码块(只加载一次)>构造块>构造方法
本地方法接口:
- Thread线程类中由native修饰的方法,代表这个方法调用的是底层操作系统和第三方C语言函数库方法, 该方法存放在本地方法栈,其他普通方法存放在java栈。
new Thread().start()只是新建完成到就绪状态,是否被运行决定于底层操作系统和CPU的调度
- Thread线程类中由native修饰的方法,代表这个方法调用的是底层操作系统和第三方C语言函数库方法, 该方法存放在本地方法栈,其他普通方法存放在java栈。
方法区:java8开始叫元空间
- 所有线程共享,存在GC,只是量很少,大部分GC在堆里
- 供各线程共享的运行时内存区域,用于存放每一个类的结构信息,例如运行时常量池、字段和方法数据、构造方法和普通方法的字节码内容、模板Class、static变量。方法区是规范,不同虚拟机实现不同,例如永久代PermGen space 和 元空间 Metaspace
- java7之前:
方法区 f = new 永久代java8之后:方法区 f = new 元空间
类的实例方法和实例对象存在堆内存中,和方法区无关
PC寄存器(程序计数器)
- 也叫程序计数器,就是一个指针,存放下一条指令的地址,指向下一条要执行的命令,记录了方法之间的调用和执行情况
- 每个线程都有一个程序计数器,和栈一样都是线程私有的,内存很小几乎不存在GC,不会发生内存溢出
如果执行的是Native方法,那这个计数器为空
栈stack(Java栈):
栈管运行,堆管存储。在Java中,程序 = 框架 + 业务逻辑
线程私有,不存在GC问题,8中基本类型变量+对象的引用变量+实例方法都是在函数的栈内存中分配
Java方法被压到栈中,叫做栈帧, main方法最先被压栈,栈帧是内存区,是有关方法和运行期数据的数据集
栈帧中主要保存三类数据:(栈中的数据都是以栈帧的格式存在,在JVM栈里方法叫栈帧,在JVM外叫方法)
- 本地变量:输入参数和输出参数以及方法内的变量
- 栈操作:记录出栈、入栈的操作
- 栈帧数据:包括类文件、方法等
栈运行原理:

栈溢出错误SOF:StackOverflowError
A a = new A();等号左边是引用,在栈里,等号右边是实例对象,在堆里;栈、堆和方法区的交互关系:
- HotSpot(JVM名)使用指针的方式来访问对象,Java堆会存放访问
类元数据(Class模板)的地址,reference存储对象的地址 
- HotSpot(JVM名)使用指针的方式来访问对象,Java堆会存放访问
堆(heap)(Java7之前):逻辑上分为以下三部分:

- 1.新生代(PSYoungGen):
- 1.伊甸区(Eden Space): new对象存在该区,GC(也叫 YGC 或轻GC 或 MinorGC)在该区产生;在内存超过阈值时开启GC之后,除了正被引用的对象和静态变量被移动到S0区,未存活的对象 被 JVM清除
- 普通MinorGC:复制(GC复制算法复制到To区) → 清空(Eden和from全部清空) → 互换(S0和S1互换,谁空谁是to区)
- 复制:第一次GC将Eden区存活的对象复制到S0区后清空Eden区,再次GC后会扫描Eden和S0区进行GC,回收存活的对象并复制到to区(如果有对象的年龄到达老年区的标准则复制到老年区),同时把这些对象年龄+1,以后每次都需要扫描Eden区和S0和S1区,进行MinorGC过程
- 清空:清空Eden和from区的对象,也即复制之后有交换,谁空谁是to区
- 交换:To区和From区互换,部分MinorGC存活到15时(由MaxTenuringThreshold决定默认15)后, 存入老年代
- 普通MinorGC:复制(GC复制算法复制到To区) → 清空(Eden和from全部清空) → 互换(S0和S1互换,谁空谁是to区)
- 2.幸存者0区(Survivor 0 Space, 也叫S0 或 from区):每次GC也会进行复制清空互换的过程
- 3.幸存者1区(Survivor 1 Space,也叫S1 或 to区):与S0区机制相同
- 1.伊甸区(Eden Space): new对象存在该区,GC(也叫 YGC 或轻GC 或 MinorGC)在该区产生;在内存超过阈值时开启GC之后,除了正被引用的对象和静态变量被移动到S0区,未存活的对象 被 JVM清除
- 2.老年代(养老区ParOldGen):当对象超过内存阈值后,开启Full GC(也叫FGC或重GC或全局GCMajorGC),多次FGC后无法再腾出空间,将抛出OOM(
OutOfMemoryError)堆内存溢出错误,Major GC比 Minor GC慢上十倍左右,每次Major GC经常(不是绝对)伴随一次Minor GC - 3.元空间Metaspace(Java7叫永久代或持久代):
- 用于存放JDK自身携带的Class,Interface的元数据(结构信息),也就是运行环境必须的类信息。被装载进此区域的数据不会被GC,关闭JVM才会释放此区域所占用的内存
- 对应方法区,虽然逻辑上JVM规范将方法区描述为堆的一个逻辑部分,但物理上不包含在堆里。元空间是方法区的一个实现,即方法区是接口,元空间是实现。
- 永久代和元空间最大区别:永久代使用JVM的堆内存,而Java8之后的元空间存在于本机物理内存,字符串常量池也在元空间
堆内存调优
- 元空间存在于本机物理内存,只受本地内存限制,字符串常量池也在元空间,减少了OOM,默认最大JVM Heap堆内存-Xmx只用物理内存的1/4, 最小堆内存-Xms为物理内存的1/64
Runtime.getRuntime().totalMemory;// 获取最大堆内存, Runtime.getRuntime()为Runtime Data Area对象- JVM调参:
- -Xms应该等于-Xmx,避免GC和应用程序争抢内存而导致JVM理论值忽高忽低的问题
GC算法(分代收集算法):只需知道是什么?怎么用?各自的优缺点
1.引用计数法(了解即可):每次GC一个对象被引用就+1,没被引用-1,当为0时就清除。System.gc 不会立刻开启GC
2.复制算法(Copying):年轻代中使用的Minor GC采用的主要是复制算法
- 是什么:Minor GC的复制过程用到的算法,复制时内存分为两块,一块移动到to区,另一块被清除
- 优缺点:优点是效率高,不会产生内存碎片, 缺点是耗费空间
3.标记清除:老年代一般是由标记清除或者标记清除与标记整理的混合实现
是什么:先扫描并标记要回收的对象,接着再扫描一次,然后统一回收这些标记的对象
优缺点:优点是不需要额外空间,缺点是两次扫描耗时严重,会产生内存碎片
4.标记压缩(标记整理):
- 是什么:相当于标记清除,加上移动对象使内存碎片清除
- 优缺点:优点:标记清除的优点+无内存碎片 缺点:耗时最长
- 是什么:相当于标记清除,加上移动对象使内存碎片清除
标记清除压缩:标记清除和标记压缩的结合,不同的是:进行多次GC后才压缩,不算入四大算法
没有最好的算法,只有根据每一代GC的特性来采用对应的算法,因此叫分代收集算法
JMM(Java内存模型):可见性、原子性、有序性
JVM是一种抽象概念,描述一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段 、静态字段和守城数组对象的元素)的访问方式
volatile是jVM提供的轻量级同步机制
1.可见性:就是个通知机制,一个线程对共享变量的修改,能及时的被其他线程看到
2.原子性:操作不可拆分,要么全成功,要么就不做
3.有序性:如果在本线程内观察,所有操作都是有序的
JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(也叫栈空间),工作内存是每个线程的私有数据区域
JMM规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作必须在工作内存中进行,首先要将变量从主内存拷贝到自己的工作内存空间,再对变量进行操作,完成后再将变量写回主内存 。不能直接操作主内存中的变量,各个线程中的工作内存中存储着主内存中的变量副本拷贝,因此不同线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主内存来完成
JUC:java.util.concurrent (Java并发编程工具类)
一般面试提问:面向对象和高级语法、Java集合类、Java多线程、JUC 和高并发、Java IO和 NIO
获取多线程的4种方法:
1.继承Thread类,重写run方法(其实Thread类本身也实现了Runnable接口)
2.实现Runnable接口,重写run方法
3.实现Callable接口,重写call方法(有返回值)
4.使用线程池(有返回值):通过Executors提供四种线程池
进程:
- 笔试:具有一定独立功能的程序关于某个数据集合的一次运行活动,是操作系统动态执行的基本单位。
- 面试:后台运行的一个程序,进程跟操作系统有关,跟编程语言无关,
线程:
笔试:一般一个进程包含多个线程,线程可以利用进程所拥有的资源,在引入线程的操作系统中,把线程作为独立运行和独立调度的基本单位
面试:线程是进程的组成部分,一般一个进程包含多个线程,它代表了一条顺序的执行流。
并发:在同一实体上的两个或多个使事件在同一时间段内发生
并行:在不同实体上的两个或多个事件在同一时刻发生
高内聚:类与类、对象与对象、模块与模块之间高度地聚集和关联
低耦合:AB两个对象可以进行数据共享,但是AB两个对象又各自 独立
在高内聚低耦合的前提下,线程(thread.start())操作(对外暴露的调用方法)资源类(操作的对象):
Thread.currentThread().getName()获取当前线程名Thread(Runnable target, String name)// target:Runnable接口的run() 方法的实现, name:线程名
尚硅谷阳哥JVM笔记的更多相关文章
- 尚硅谷STRUTS2视频学习笔记
上一个月一直在学习STRUTS2,学习的是尚硅谷佟刚老师的视频,因为很喜欢佟刚老师的声音,而且他讲的很细,笔记做的也多,基本上是照着他的视频完整的敲了一遍代码,下面就把学习到的知识梳理一遍,最后把项目 ...
- 尚硅谷MySQL高级学习笔记
目录 数据库MySQL学习笔记高级篇 写在前面 1. mysql的架构介绍 mysql简介 mysqlLinux版的安装 mysql配置文件 mysql逻辑架构介绍 mysql存储引擎 2. 索引优化 ...
- 尚硅谷MySQL基础学习笔记
目录 写在前面 MySQL引入 数据库的好处 数据库的相关概念 数据库存储数据的特点 MySQL服务的启动和停止 MySQL服务端的登录和退出 MySQL的常用命令 MySQL语法规范 DQL(Dat ...
- 尚硅谷Oracle教程-学习笔记2
控制用户权限 1.创建用户 1) SQL> create user atguigu01 2 identified by atguigu01; User created 2) SQL> gr ...
- 尚硅谷Java基础学习笔记
综述: Java学习图谱: 常见dos命令: 操作案例: Java语言的特点: 面向对象 两个基本概念:类.对象 三个基本特性:封装.继承.多态 健壮性.可继承性 write once,run any ...
- Spring学习笔记 1. 尚硅谷_佟刚_Spring_HelloWorld
1,准备工作 (1)安装spring插件 搜索https://spring.io/tools/sts/all就可以下载最新的版本 下载之后不用解压,使用Eclipse进行安装.在菜单栏最右面的Help ...
- 尚硅谷spring_boot课堂笔记
尚硅谷spring_boot课堂笔记
- 尚硅谷韩顺平Linux教程学习笔记
目录 尚硅谷韩顺平Linux教程学习笔记 写在前面 虚拟机 Linux目录结构 远程登录Linux系统 vi和vim编辑器 关机.重启和用户登录注销 用户管理 实用指令 组管理和权限管理 定时任务调度 ...
- 保姆级尚硅谷SpringCloud学习笔记(更新中)
目录 前言 正文内容 001_课程说明 002_零基础微服务架构理论入门 微服务优缺点[^1] SpringCloud与微服务的关系 SpringCloud技术栈 003_第二季Boot和Cloud版 ...
随机推荐
- VMware Workstation 15 Pro安装带图形化界面的CentOS7
1.双击打开“VMware Workstation”,然后选择“创建新的虚拟机” 2.在安装向导中,选择“稍后安装操作系统”,然后点击“下一步”继续安装 3.在“客户机操作系统”中选择“Linux(L ...
- C# WebAPI项目,不支持HttpPut请求!!!
有点标题党了,这个异常的现象是这样的: 我有一个正在跑的项目,要对接第三方厂家的设备. 对方给的接口文档,里面有一个接口是需要我这边实现的,要求必须是PUT请求方式. 所以我在项目基础上,新增一个W ...
- 数据结构与算法笔记(java)目录
数据结构: 一个动态可视化数据结构的网站 线性结构 数组 动态数组 链表 单向链表 双向链表 单向循环链表 双向循环链表 栈 栈 队列 队列 双端队列 哈希表 树形结构 二叉树 二叉树 二叉搜索树 A ...
- Jmeter(二十二) - 从入门到精通 - JMeter断言 - 下篇(详解教程)
1.简介 断言组件用来对服务器的响应数据做验证,常用的断言是响应断言,其支持正则表达式.虽然我们的通过响应断言能够完成绝大多数的结果验证工作,但是JMeter还是为我们提供了适合多个场景的断言元件,辅 ...
- springmvc中get和post区别和应用
最近对post和get什么时候使用 和 应该怎么使用 他俩的区别 有了一些疑问 根据本人的了解 post是对数据进行了封装保护 get是安全性较差的 可以看到数据的信息 post是用来改 ...
- 利用JavaScript当鼠标点击导航时改变背景
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 多元线性回归检验t检验(P值),F检验,R方等参数的含义
做线性回归的时候,检验回归方程和各变量对因变量的解释参数很容易搞混乱,下面对这些参数进行一下说明: 1.t检验:t检验是对单个变量系数的显著性检验 一般看p值: 如果p值小于0.05表示该自 ...
- HTML5实战与剖析之媒体元素
随着HTML5的到来,flash在手机端全部不能得到支持,这就使一项以flash制作的音乐播放和视频播放只能用HTML5中的媒体标签video标签和audio标签来制作了.很恰巧的是,移动端对HTML ...
- 方差分析、T检验、卡方分析如何区分?
差异研究的目的在于比较两组数据或多组数据之间的差异,通常包括以下几类分析方法,分别是方差分析.T检验和卡方检验. 三个方法的区别 其实核心的区别在于:数据类型不一样.如果是定类和定类,此时应该使用卡方 ...
- zero:如何找到SEO流量的突破口
http://www.wocaoseo.com/thread-326-1-1.html 之前一篇文章已有提到过,SEO可以分为两个阶段: 一个阶段是了解点SEO知识,然后就到网站上去找页面,看哪些招式 ...