自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(42)
  • 收藏
  • 关注

原创 JVM-10——方法区

方法区 栈、堆、方法区的交互关系 方法区的理解 设置方法区大小与OOM 方法区内部结构 方法区的演进细节 方法区的GC 总结 1. 堆、栈、方法区的交互关系 2. 方法区的理解 方法区在哪里? 尽管JVM规范中说明,方法区在逻辑上属于堆的一部分,但是一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。 对于HotSpot而言,方法区还有一个名字叫做“Non-Heap”,目的是要和堆分开 所以,方法区看做是一块独立于java堆的内存空间。 理解 方法区与java堆一样,是各个线程共享的内存

2020-09-07 17:13:25 309

原创 JVM-9——堆

堆 堆的核心概述 设置堆的内存大小与OOM 年轻代与老年代 对象分配过程 Minor GC、Major GC 、Full GC 堆空间分代思想 内存分配策略 为对象分配内存:TLAB 堆空间的参数设置 堆是分配对象的唯一选择吗? 1. 堆(heap) 的核心概述 一个JVM实例只存在一个堆空间,堆也是java内存管理的核心区域 java堆区在JVM启动的时候即被创建,其空间大小也就确定了。是JVM管理的最大一块内存空间 堆内存大小是可以调节的 《java虚拟机规范》规定,堆可以处于物理上不连续

2020-09-07 17:11:52 341

原创 JVM-8——本地方法栈

本地方法栈 什么是本地方法? 简单来讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java方法:该方法的实现由非java语言实现。 在定义一个native method时,并不提供实现体(有些像定义一个java interface),因为其实现体是由非java语言在外面实现的。 本地接口的作用是融合不同的编程语言为java所用,它的初衷是融合C/C++程序。 使用native标识符修饰的方法就是本地方法 为什么要使用Native Me

2020-09-04 21:45:31 3688

原创 JVM-7——栈面试

栈的相关面试题 举例栈溢出的情况? StackOverflowError 通过-Xss设置栈的大小 动态分配时超过内存大小会出现OOM 调整栈大小,就能保证不出现溢出吗? 不能 需要根据实际情景进行设置 分配的栈内存越大越好吗? 不是 短期内会有优点,但是会挤占其他的内存空间 只能延缓SOE的出现时间,但不能避免 垃圾回收是否会涉及到虚拟机栈? 不会 GC只负责方法区和堆空间 线程私有的部分(本地方法栈,虚拟机栈,PC寄存器)不会被GC 方法中定义的局部变量是否线程安全? 如果只有一个线程

2020-09-04 21:44:51 201

原创 JVM-6——虚拟机栈

虚拟机栈 1. 基本内容 Java虚拟机栈是什么? 每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次的Java方法调用。且虚拟机栈是私有的。 生命周期 生命周期和线程一致 作用 主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回。 2. 栈的特点 栈是一种快速有效的分配存储方式,访问速度仅次于程序计数器 JVM直接对Java栈的操作只有两个 每个方法执行,伴随着入栈 执行结束后的出栈工作 对于栈来说不

2020-08-27 10:56:53 337

原创 JVM-5——PC寄存器

PC寄存器 概述 JVM中的程序计数寄存器(Program Counter Register),并非是广义上所指的物理寄存器,而是对物理PC寄存器的一种抽象模拟。 它是一块很小的内存空间,几乎可以忽略不计。也是运行速度最快的存储区域。 在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致 任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者,如果是在执行native方法,则是未指定值。

2020-08-20 18:05:49 233

原创 JVM-4——类的主动被动使用

类的使用 在JVM中表示两个class对象是否为同一个类存在两个必要条件: 类的完整类名必须一致,包括包名 加载这个类的ClassLoader(指ClassLoader实例对象)必须相同 换句话说,在JVM中,即使这两个类对象来源于同一个class文件,被同一个虚拟机所加载,但只要加载他们的ClassLoader实例对象不同,那么这两个类对象也是不相等的。 对类加载器的引用 JVM必须知道一个类型是由启动加载器加载的还是由用户类加载器加载的。如果一个类型是由用户类加载器加载的,那么JVM会将这个类加

2020-08-20 12:50:05 414

原创 JVM-3——双亲委派机制

双亲委派机制 Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存生成class对象。而且加载某个类class文件时,Java虚拟机采用的是双亲委派模式,即把请求交由父类处理,它是一种任务委派模式。 1. 工作原理 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行; 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器; 如果父类加载器可以完成类加载任

2020-08-20 12:49:34 254

原创 JVM-2——类加载器子系统

类加载器子系统 1. 作用 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4d9Hjz1T-1597850578798)(https://i.loli.net/2020/08/19/YzEHaQvp156D2We.png)] 类加载器子系统负责从文件系统或者网络中加载Class文件,Class文件在文件开头有特定的文件标识。 ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定 加载的类信息存放于一块称为方法区的内

2020-08-19 23:23:46 163

原创 JVM-1——生命周期

JVM 1. JVM的生命周期 虚拟机的启动 Java虚拟机的启动是通过引导类加载器创建一个**初始类 (initial class)**来完成的,这个类是由虚拟机的具体实现指定的。 虚拟机的执行 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序 程序开始执行时他才运行,程序结束时他就停止 执行一个所谓的Java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程 虚拟机的退出 程序正常执行结束 程序在执行过程中遇到了异常或错误而异常终止 由于操作系统出现错误而导致Java虚拟机

2020-08-19 10:33:06 222

原创 MySQL(2)——索引

索引 1. 什么是索引? 索引是帮助MySQL高校获取数据的数据结构 索引存储在文件系统中 索引的文件存储形式与存储引擎有关 索引文件的结构 hash 二叉树 B树 B+树 2. 索引的分类 MySQL索引有五种类型。通过给字段添加索引可以提高数据的读取速度,提高项目的并发能力和抗压能力。 主键索引 主键是一种唯一性索引,但它必须指定为PRIMARY KEY,每个表只能有一个主键。 唯一索引 索引列的所有值只能出现一次,即必须唯一,值可以为空。 普通索引 基本的索引类型,值可以为空

2020-08-17 17:12:38 165

原创 MySQL(1)——存储引擎

MySQL存储引擎 1. 什么是存储引擎? 存储引擎就是如何存储数据、如何为存储的数据建立索引、如何更新、查询数据等技术的实现方法。因为在关系数据库中数据是以表的形式存储的,所以存储引擎也可以称为表类型(即存储和操作此表的类型)。在Oracle和SQLServer等数据库中只有一种存储引擎,所有的数据存储管理机制都是一样的;而MySQL数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据需要编写自己的存储引擎。 数据库存储引擎是数据库底层软件组件,数据库管理系统使

2020-08-16 17:24:46 376

原创 JavaSE(27)——并发工具类

并发工具类 java为开发者提供了三个同步工具类,说白了就是为了能够更好控制线程之间的通讯问题。 CountDownLatch (闭锁) CyclicBarrier (栅栏) Semaphore (信号量) 1. CountDownLatch CountDownLatch是一个同步的辅助类,允许一个或多个线程一直等待,直到其他线程完成他们的操作。 常用的API有两个:await()和countDown() count初始化CountDownLatch,然后需要等待的线程调用await方法。await

2020-08-15 16:56:32 180

原创 JavaSE(26)——死锁

死锁 1. 造成死锁的原因 当前线程拥有其他线程需要的资源 当前线程等待其他线程已拥有的资源 都不放弃自己拥有的资源 2. 死锁的种类 2.1 锁顺序死锁 public class Test{ private Object A = new Object(); private Object B = new Object(); public void ab(){ synchronized(A){ synchronized(B){

2020-08-14 20:46:16 205

原创 JavaSE(25)——阻塞队列

阻塞队列 操作 抛出异常 有返回值,不抛异常 阻塞等待 超时等待 插入 add offer put offer() 删除 remove poll take poll() 获取 element peek ArrayBlockingQueue 属性 //队列元素 final Object[] items; //下一个元素的下标(被take,poll,peek,remove) int takeIndex; //下一个元素的下标(被put,offer,add

2020-08-14 19:29:16 150

原创 JavaSE(24)——线程池详解

线程池详解 1. 线程池的意义 线程是稀缺资源,它的创建与销毁是比较重且耗资源的操作。而Java线程依赖于内核线程,创建线程需要进行操作系统状态切换,为避免资源过度消耗需要设法重用线程执行多个任务,线程池就是一个线程缓存,负责对线程进行统一分配,调优与监控。 线程池的优势: 重用存在的线程,减少线程创建、消亡的开销,提高性能 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行任务。 提高线程的可管理性。线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程

2020-08-14 14:07:43 207

原创 JavaSE(23)——ReentrantReadWriteLock源码

ReentrantReadWriteLock源码 1. 源码注释 在java中,synchronized内置锁和ReentrantLock都是互斥锁,一次只能有一个线程进入到被临界区。 而ReentrantReadWriteLock是一个读写锁: 在读取数据的时候,可以多个线程同时进入到临界区内 在写入数据的时候,无聊是读线程还是写线程,都是互斥的。 一般情况下,大多数都是读数据多,写数据少的情景。这种时候使用读写锁就非常合适了。 ReadWriteLock源码注释: 维护了一对锁 读锁可同时进入到

2020-08-13 16:45:59 160

原创 JavaSE(22)——ReentrantLock源码

ReentrantLock源码 1. 源码注释 跟synchronized具有相同的功能和语义(都是互斥锁),但它具有更好的拓展性。 通过这两个方法判断当前线程是否拥有锁 isHeldByCurrentThread getHoldCount 构造方法支持使用参数来让锁设计为公平锁,公平锁一般的吞吐量会低一些,但一定程度保住了“相对公平” 不计时 tryLock()方法不符合公平锁的设定 在try代码块之前调用lock,这是最应该使用的方式 Lock接口还定义了一些监听锁状态的方法

2020-08-13 12:17:06 186

原创 JavaSE(21)——java的各种锁详细介绍

java的各种锁详细介绍 1. 乐观锁和悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。在java和数据库中都有实际应用。 对于一个数据的并发操作 悲观锁认为,自己在使用数据的时候一定有别的线程来修改数据,因而在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。 乐观锁认为,自己在使用数据的时候不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据

2020-08-12 12:47:20 323

原创 JavaSE(20)——java锁机制

java锁机制 1. synchronized锁 1.1 定义 synchronized是java的一个关键字,它能够将代码块(方法)锁起来 它使用起来是非常简单的,只要在代码块(方法)添加synchronized,即可以实现同步功能。 public sychronized void test(){} synchronized是一种互斥锁 一次只能允许一个线程进入被锁住的代码块 synchronized是一种内置锁/监视器锁 Java中每一个对象都有一个内置锁 (监视器,也可以理解成锁标

2020-08-11 18:20:51 479

原创 JavaSE(19)——多线程知识点

多线程知识点 多线程使用的问题 线程安全问题 多个线程操作共享变量产生的问题 线程性能问题 在共享方法上使用synchronized关键字可以解决线程安全问题,但是带来了严重的性能问题 解决方法 使用多线程时,一定要保证线程是安全的。解决线程安全问题的方法: 无状态 (没有共享变量) 使用final使该引用变量不可变 (如果该对象也引用了其他对象,那么无论是发布还是使用都需要加锁) 加锁 (内置锁,显式Lock锁) 使用JDK提供的线程安全类 原子性 (可以使用AtomicLong等类来

2020-08-11 13:59:38 135

原创 JavaSE(18)——Thread源码

Thread源码 1. Thread类API 1.1 设置线程名 public class Thread implements Runnable { //默认使用的线程名是“Thread-X” public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); } public final synchronized void setName(String name) {

2020-08-09 23:08:03 150

原创 JavaSE(17)——多线程入门

多线程入门 1. 多线程的认识 1.1 什么是进程 ​ 进程是程序的一次执行,进程是一个程序及其数据在处理机上顺序执行时所发生的活动,进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的独立单位。每一个进程都有它自己的内存空间和系统资源 1.2 什么是线程 ​ 为使程序能并发执行,系统必须进行以下的一系列操作: 创建进程,系统在创建一个进程时,必须为它分配其所必需的、除处理机以外的所有资源,如内存空间、IO设备,以及建立相应的PCB (进程控制块); 撤销进程,系统在撤销

2020-08-08 20:43:09 288

原创 JavaSE(16)——ThreadLocal

ThreadLocal 1. 概述 This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the vari

2020-08-08 19:20:28 149

原创 JavaSE(15)——多线程起源

多线程起源 1. 为什么使用多线程? 首先需要明确的一点,为什么要使用多线程? 在一般人看来,使用多线程是为了加快程序运行的速度。 其实不然,使用多线程最主要的原因是提高系统的资源利用率。 现在的CPU基本都是多核的,如果只用单线程的话,就只用到了一个核心,其他的核心都在闲置。 CPU的核心有五个,如果只使用一个核心,那工作效率如何?比如现在有5个程序需要执行。 在单线程的时候,一个程序的执行需要10分钟,但是后面的程序都得等一个核心,那总共花费的时间就是50分钟。 而在多线程情况下,一个程序开始执行,

2020-08-08 14:39:56 242

原创 JavaSE(14)——CopyOnWriteArrayList

CopyOnWriteArrayList解析 1. Vector和SynchronizedList 1.1 回顾 ​ 众所周知,ArrayList是用于替代Vector的,Vector是线程安全的容器,因为它几乎在每个方法声明处都加了synchronized关键字来使容器安全。 ​ 如果使用Collections.synchronizedList(new ArrayList())来使得ArrayList线程安全的话,也是几乎在每个方法上都加上了synchronized关键字,不同的是,它是加在方法内部,

2020-08-08 14:38:33 178

原创 JavaSE(13)——Java集合总结

java集合总结 1. 概述 java容器可分为两大类 Collection List ArrayList LinkedList Vector (了解即可,已过时) Set TreeSet HashSet LinkedHashSet Map HashMap LinkedHashMap TreeMap ConcurrentHashMap HashTable (了解即可,已过时) 2. ArrayList和Vector的区别 共同点 这两个类都实现了List接口 都是

2020-08-07 13:48:32 220

原创 JavaSE(12)——Set集合

Set集合 1. 概述 Set集合主要有三个子类: HashSet 底层数据结构是哈希表+红黑树 TreeSet 底层数据结构是红黑树 保证元素的排序方式 LinkedHashSet 底层数据结构由哈希表和双向链表组成 2. HashSet解析 2.1 继承结构图 2.2 特征 实现Set接口 不保证迭代顺序 允许元素为null 底层实际上是一个HashMap实例 非同步 初始容量非常影响迭代性能 2.3 属性 //存储时用的map private transient

2020-08-07 11:17:42 230

原创 JavaSE(11)——ConcurrentHashMap源码

ConcurrentHashMap源码 1. 类概述 1.1 概述 ConcurrentHashMap底层是散列表+红黑树实现的,与HashMap一样 支持高并发的检索和更新 线程安全并且检索操作不会加锁 检索出来的结果是最新设置的值 一些统计方法,例如 size() 、isEmpty()、 containsValue(),最好是在单线程的环境下使用,不然它只满足监控或估算的目的,在项目中 (多环境下)使用它是无法准确返回的 当有太多的散列碰撞时,该表会动态增长 再散列 (扩容) 是一件非常耗费资源的

2020-08-06 22:47:22 207

原创 力扣146题——LRU缓存机制

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。 获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。 写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。 进阶: 你是否可以在 O(.

2020-08-05 19:59:35 413

原创 JavaSE(10)——TreeMap源码

TreeMap源码 1. 概述 1.1 描述 底层是红黑树,实现了NavigableMap接口,可以根据Key自然排序,也可以在构造方法上传递Comparator实现Map的排序 其中,containsKey、get、put、remove这些方法的时间复杂度是log(n) 有序的Map中,一般是使用compareTo或者Compare方法来比较key,只要该两个方法认为相等,在Map的角度就认为这两个元素相等 TreeMap非同步 1.2 继承关系 1.3 特点 TreeMa

2020-08-05 17:45:32 130

原创 JavaSE(9)——LinkedHashMap源码

LinkedHashMap源码 1. 特征 底层是散列表和双向链表 允许为null,不同步 插入顺序是有序的 (底层链表致使有序) 负载因子和初始容量对LinkedHashMap影响很大 问题: access-ordered和insertion-ordered具体的使用和意思 为什么说初始容量对遍历没有影响? 2. 属性 /** * 在原有的HashMap中的Node中,加入了before和after属性 */ static class Entry<K,V> extends Has

2020-08-05 10:59:45 152

原创 JavaSE(8)——HashMap源码

HashMap源码解析 1 Hash的来由 1.1 数组的优劣势 优势 检索速度快 按索引遍历方便 能存储大量数据 劣势 占用空间多,浪费 数组大小固定,一经确定不能改变 只能存储一种类型的数据 增加删除效率低 1.2 链表的优劣势 优势 增删元素效率高 内存利用率高,不浪费内存 大小不固定,拓展灵活 劣势 检索需要遍历节点,效率低 1.3 整合两种数据结构的优势 散列表 散列表,又叫哈希表(Hash Table),是能够通过给定的关键字的值直接访问到具

2020-08-04 16:55:42 147

原创 JavaSE(7)——红黑树的实现

红黑树左旋: p p | | X y / \ ====> / \ lx y x ry / \ / \ ly ry lx ly 红黑树右旋: p p | | y

2020-08-02 23:54:51 193

原创 JavaSE(6)——Map集合

Map集合 1. Map介绍 1.1 为什么需要Map Set集合是为了存储对象,快速查找而产生的,类似对象数组。而Map不同,Map的结构在官方的解释中被称为——“映射”。 映射的模型是一个Key对应一个Value,用Key来区别不同的Value。 比如,作为学生来说,根据学号可以区分不同的学生,只要知道学号,就可以获取对应的学生信息。比如身份证,通过身份证(key)就可以证明自己(value)。 1.2 Map与Collection的区别 Map集合的特点:将键映射到值的对象,一个映射不能包含重复的键,

2020-08-01 17:07:11 156

原创 JavaSE(5)——List集合

List集合 List集合的三个子类: ArrayList 底层使用数组结构,线程不安全 LinkedList 底层使用链表结构,线程不安全 Vector 底层使用数组结构,线程不安全 ArrayList解析 ArrayList是我们平时使用非常多的一个集合。 属性 private static final long serialVersionUID = 8683452581122892189L; private static final int DEFAULT_CAPACITY = 1

2020-08-01 13:25:26 233

原创 JavaSE(4)——Collection集合

java中的集合(Collection) 1. 为什么需要Collection java是面向对象的语言,需要对对象进行一系列操作 为了操作一堆对象,就需要把这么多对象存储起来 存储时就需要一个装对象的容器 因此,JDK中提供了集合(Collection)来处理若干对象 2. 数组和集合的区别 长度区别 数组长度固定 集合长度可变化 内容不同 数组中只能存储同一种类型的元素 集合可以存储不同类型的元素(一般情况下只存相同类型元素) 元素数据类型 数组中可以存基本数据

2020-07-31 18:17:34 163

原创 JavaSE(3)——数组及排序

java中的数组 数组的初始化大致有三种写法,一种动态初始化和两种静态初始化。 动态初始化: int[] a = new int[length]; //length必须指定且为正整数 静态初始化: int[] a = new int[]{1,2,3,4}; int[] a = {1,2,3,4}; 对数组的循环有fori和foreach两种写法 java中的排序 选择排序 public static void sort (int[] arr){ for (int i = 0; i &lt

2020-07-28 18:58:11 136

原创 JavaSE(2)——运算符

java的运算符 java的运算符和C++用法基本相同,分别有算术、赋值、关系、逻辑、位和三元运算符 算术运算符 运算符 含义 + 加运算 - 减运算 * 乘运算 / 除运算 % 取余运算 ++ 在当前基础上加一(符号在前时先加后使用,反之则先使用后增加) – 在当前基础上减一(符号在前时先加后使用,反之则先使用后增加) 赋值运算符 运算符 含义 = 将等号后面的值赋值给等号左边的变量 += 使等号左边的变量值加上等号右边的值 -= 使等号

2020-07-26 12:36:46 173

原创 JavaSE(1)——基本数据类型和引用数据类型

java的数据类型 java中数据类型分为两类,一类是基本数据类型,一类是引用数据类型 基本数据类型 java中一共有八种基本类型,其中有4种整型,两种浮点型,一种字符类型和一种存储真值的boolean类型 1. 整型(byte,short,int,long) 数据类型 存储位数 取值范围 byte 1字节 -128~127(±2的7次方) short 2字节 -32768~32767(±2的15次方) int 4字节 -2147483648~2147483647(±2的31次方,正

2020-07-21 20:47:47 171

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除