- 博客(42)
- 收藏
- 关注
原创 JVM-10——方法区
方法区栈、堆、方法区的交互关系方法区的理解设置方法区大小与OOM方法区内部结构方法区的演进细节方法区的GC总结1. 堆、栈、方法区的交互关系2. 方法区的理解方法区在哪里?尽管JVM规范中说明,方法区在逻辑上属于堆的一部分,但是一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。对于HotSpot而言,方法区还有一个名字叫做“Non-Heap”,目的是要和堆分开所以,方法区看做是一块独立于java堆的内存空间。理解方法区与java堆一样,是各个线程共享的内存
2020-09-07 17:13:25
226
原创 JVM-9——堆
堆堆的核心概述设置堆的内存大小与OOM年轻代与老年代对象分配过程Minor GC、Major GC 、Full GC堆空间分代思想内存分配策略为对象分配内存:TLAB堆空间的参数设置堆是分配对象的唯一选择吗?1. 堆(heap) 的核心概述一个JVM实例只存在一个堆空间,堆也是java内存管理的核心区域java堆区在JVM启动的时候即被创建,其空间大小也就确定了。是JVM管理的最大一块内存空间堆内存大小是可以调节的《java虚拟机规范》规定,堆可以处于物理上不连续
2020-09-07 17:11:52
252
原创 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
3180
原创 JVM-7——栈面试
栈的相关面试题举例栈溢出的情况?StackOverflowError通过-Xss设置栈的大小动态分配时超过内存大小会出现OOM调整栈大小,就能保证不出现溢出吗?不能需要根据实际情景进行设置分配的栈内存越大越好吗?不是短期内会有优点,但是会挤占其他的内存空间只能延缓SOE的出现时间,但不能避免垃圾回收是否会涉及到虚拟机栈?不会GC只负责方法区和堆空间线程私有的部分(本地方法栈,虚拟机栈,PC寄存器)不会被GC方法中定义的局部变量是否线程安全?如果只有一个线程
2020-09-04 21:44:51
149
原创 JVM-6——虚拟机栈
虚拟机栈1. 基本内容Java虚拟机栈是什么?每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次的Java方法调用。且虚拟机栈是私有的。生命周期生命周期和线程一致作用主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回。2. 栈的特点栈是一种快速有效的分配存储方式,访问速度仅次于程序计数器JVM直接对Java栈的操作只有两个每个方法执行,伴随着入栈执行结束后的出栈工作对于栈来说不
2020-08-27 10:56:53
242
原创 JVM-5——PC寄存器
PC寄存器概述JVM中的程序计数寄存器(Program Counter Register),并非是广义上所指的物理寄存器,而是对物理PC寄存器的一种抽象模拟。它是一块很小的内存空间,几乎可以忽略不计。也是运行速度最快的存储区域。在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者,如果是在执行native方法,则是未指定值。
2020-08-20 18:05:49
150
原创 JVM-4——类的主动被动使用
类的使用在JVM中表示两个class对象是否为同一个类存在两个必要条件:类的完整类名必须一致,包括包名加载这个类的ClassLoader(指ClassLoader实例对象)必须相同换句话说,在JVM中,即使这两个类对象来源于同一个class文件,被同一个虚拟机所加载,但只要加载他们的ClassLoader实例对象不同,那么这两个类对象也是不相等的。对类加载器的引用JVM必须知道一个类型是由启动加载器加载的还是由用户类加载器加载的。如果一个类型是由用户类加载器加载的,那么JVM会将这个类加
2020-08-20 12:50:05
339
原创 JVM-3——双亲委派机制
双亲委派机制Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存生成class对象。而且加载某个类class文件时,Java虚拟机采用的是双亲委派模式,即把请求交由父类处理,它是一种任务委派模式。1. 工作原理如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行;如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器;如果父类加载器可以完成类加载任
2020-08-20 12:49:34
169
原创 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
114
原创 JVM-1——生命周期
JVM1. JVM的生命周期虚拟机的启动Java虚拟机的启动是通过引导类加载器创建一个**初始类 (initial class)**来完成的,这个类是由虚拟机的具体实现指定的。虚拟机的执行一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序程序开始执行时他才运行,程序结束时他就停止执行一个所谓的Java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程虚拟机的退出程序正常执行结束程序在执行过程中遇到了异常或错误而异常终止由于操作系统出现错误而导致Java虚拟机
2020-08-19 10:33:06
143
原创 MySQL(2)——索引
索引1. 什么是索引?索引是帮助MySQL高校获取数据的数据结构索引存储在文件系统中索引的文件存储形式与存储引擎有关索引文件的结构hash二叉树B树B+树2. 索引的分类MySQL索引有五种类型。通过给字段添加索引可以提高数据的读取速度,提高项目的并发能力和抗压能力。主键索引主键是一种唯一性索引,但它必须指定为PRIMARY KEY,每个表只能有一个主键。唯一索引索引列的所有值只能出现一次,即必须唯一,值可以为空。普通索引基本的索引类型,值可以为空
2020-08-17 17:12:38
112
原创 MySQL(1)——存储引擎
MySQL存储引擎1. 什么是存储引擎?存储引擎就是如何存储数据、如何为存储的数据建立索引、如何更新、查询数据等技术的实现方法。因为在关系数据库中数据是以表的形式存储的,所以存储引擎也可以称为表类型(即存储和操作此表的类型)。在Oracle和SQLServer等数据库中只有一种存储引擎,所有的数据存储管理机制都是一样的;而MySQL数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据需要编写自己的存储引擎。数据库存储引擎是数据库底层软件组件,数据库管理系统使
2020-08-16 17:24:46
304
原创 JavaSE(27)——并发工具类
并发工具类java为开发者提供了三个同步工具类,说白了就是为了能够更好控制线程之间的通讯问题。CountDownLatch (闭锁)CyclicBarrier (栅栏)Semaphore (信号量)1. CountDownLatchCountDownLatch是一个同步的辅助类,允许一个或多个线程一直等待,直到其他线程完成他们的操作。常用的API有两个:await()和countDown()count初始化CountDownLatch,然后需要等待的线程调用await方法。await
2020-08-15 16:56:32
135
原创 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
148
原创 JavaSE(25)——阻塞队列
阻塞队列操作抛出异常有返回值,不抛异常阻塞等待超时等待插入addofferputoffer()删除removepolltakepoll()获取elementpeekArrayBlockingQueue属性 //队列元素 final Object[] items; //下一个元素的下标(被take,poll,peek,remove) int takeIndex; //下一个元素的下标(被put,offer,add
2020-08-14 19:29:16
108
原创 JavaSE(24)——线程池详解
线程池详解1. 线程池的意义线程是稀缺资源,它的创建与销毁是比较重且耗资源的操作。而Java线程依赖于内核线程,创建线程需要进行操作系统状态切换,为避免资源过度消耗需要设法重用线程执行多个任务,线程池就是一个线程缓存,负责对线程进行统一分配,调优与监控。线程池的优势:重用存在的线程,减少线程创建、消亡的开销,提高性能提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行任务。提高线程的可管理性。线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程
2020-08-14 14:07:43
146
原创 JavaSE(23)——ReentrantReadWriteLock源码
ReentrantReadWriteLock源码1. 源码注释在java中,synchronized内置锁和ReentrantLock都是互斥锁,一次只能有一个线程进入到被临界区。而ReentrantReadWriteLock是一个读写锁:在读取数据的时候,可以多个线程同时进入到临界区内在写入数据的时候,无聊是读线程还是写线程,都是互斥的。一般情况下,大多数都是读数据多,写数据少的情景。这种时候使用读写锁就非常合适了。ReadWriteLock源码注释:维护了一对锁读锁可同时进入到
2020-08-13 16:45:59
119
原创 JavaSE(22)——ReentrantLock源码
ReentrantLock源码1. 源码注释跟synchronized具有相同的功能和语义(都是互斥锁),但它具有更好的拓展性。通过这两个方法判断当前线程是否拥有锁isHeldByCurrentThreadgetHoldCount构造方法支持使用参数来让锁设计为公平锁,公平锁一般的吞吐量会低一些,但一定程度保住了“相对公平”不计时 tryLock()方法不符合公平锁的设定在try代码块之前调用lock,这是最应该使用的方式Lock接口还定义了一些监听锁状态的方法
2020-08-13 12:17:06
130
原创 JavaSE(21)——java的各种锁详细介绍
java的各种锁详细介绍1. 乐观锁和悲观锁乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。在java和数据库中都有实际应用。对于一个数据的并发操作悲观锁认为,自己在使用数据的时候一定有别的线程来修改数据,因而在获取数据的时候会先加锁,确保数据不会被别的线程修改。Java中,synchronized关键字和Lock的实现类都是悲观锁。乐观锁认为,自己在使用数据的时候不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据
2020-08-12 12:47:20
221
原创 JavaSE(20)——java锁机制
java锁机制1. synchronized锁1.1 定义synchronized是java的一个关键字,它能够将代码块(方法)锁起来它使用起来是非常简单的,只要在代码块(方法)添加synchronized,即可以实现同步功能。public sychronized void test(){}synchronized是一种互斥锁一次只能允许一个线程进入被锁住的代码块synchronized是一种内置锁/监视器锁Java中每一个对象都有一个内置锁 (监视器,也可以理解成锁标
2020-08-11 18:20:51
340
原创 JavaSE(19)——多线程知识点
多线程知识点多线程使用的问题线程安全问题多个线程操作共享变量产生的问题线程性能问题在共享方法上使用synchronized关键字可以解决线程安全问题,但是带来了严重的性能问题解决方法使用多线程时,一定要保证线程是安全的。解决线程安全问题的方法:无状态 (没有共享变量)使用final使该引用变量不可变 (如果该对象也引用了其他对象,那么无论是发布还是使用都需要加锁)加锁 (内置锁,显式Lock锁)使用JDK提供的线程安全类原子性 (可以使用AtomicLong等类来
2020-08-11 13:59:38
83
原创 JavaSE(18)——Thread源码
Thread源码1. Thread类API1.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
100
原创 JavaSE(17)——多线程入门
多线程入门1. 多线程的认识1.1 什么是进程 进程是程序的一次执行,进程是一个程序及其数据在处理机上顺序执行时所发生的活动,进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的独立单位。每一个进程都有它自己的内存空间和系统资源1.2 什么是线程 为使程序能并发执行,系统必须进行以下的一系列操作:创建进程,系统在创建一个进程时,必须为它分配其所必需的、除处理机以外的所有资源,如内存空间、IO设备,以及建立相应的PCB (进程控制块);撤销进程,系统在撤销
2020-08-08 20:43:09
223
原创 JavaSE(16)——ThreadLocal
ThreadLocal1. 概述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
113
原创 JavaSE(15)——多线程起源
多线程起源1. 为什么使用多线程?首先需要明确的一点,为什么要使用多线程?在一般人看来,使用多线程是为了加快程序运行的速度。其实不然,使用多线程最主要的原因是提高系统的资源利用率。现在的CPU基本都是多核的,如果只用单线程的话,就只用到了一个核心,其他的核心都在闲置。CPU的核心有五个,如果只使用一个核心,那工作效率如何?比如现在有5个程序需要执行。在单线程的时候,一个程序的执行需要10分钟,但是后面的程序都得等一个核心,那总共花费的时间就是50分钟。而在多线程情况下,一个程序开始执行,
2020-08-08 14:39:56
177
原创 JavaSE(14)——CopyOnWriteArrayList
CopyOnWriteArrayList解析1. Vector和SynchronizedList1.1 回顾 众所周知,ArrayList是用于替代Vector的,Vector是线程安全的容器,因为它几乎在每个方法声明处都加了synchronized关键字来使容器安全。 如果使用Collections.synchronizedList(new ArrayList())来使得ArrayList线程安全的话,也是几乎在每个方法上都加上了synchronized关键字,不同的是,它是加在方法内部,
2020-08-08 14:38:33
136
原创 JavaSE(13)——Java集合总结
java集合总结1. 概述java容器可分为两大类CollectionListArrayListLinkedListVector (了解即可,已过时)SetTreeSetHashSetLinkedHashSetMapHashMapLinkedHashMapTreeMapConcurrentHashMapHashTable (了解即可,已过时)2. ArrayList和Vector的区别共同点这两个类都实现了List接口都是
2020-08-07 13:48:32
160
原创 JavaSE(12)——Set集合
Set集合1. 概述Set集合主要有三个子类:HashSet底层数据结构是哈希表+红黑树TreeSet底层数据结构是红黑树保证元素的排序方式LinkedHashSet底层数据结构由哈希表和双向链表组成2. HashSet解析2.1 继承结构图2.2 特征实现Set接口不保证迭代顺序允许元素为null底层实际上是一个HashMap实例非同步初始容量非常影响迭代性能2.3 属性//存储时用的mapprivate transient
2020-08-07 11:17:42
168
原创 JavaSE(11)——ConcurrentHashMap源码
ConcurrentHashMap源码1. 类概述1.1 概述ConcurrentHashMap底层是散列表+红黑树实现的,与HashMap一样支持高并发的检索和更新线程安全并且检索操作不会加锁检索出来的结果是最新设置的值一些统计方法,例如 size() 、isEmpty()、 containsValue(),最好是在单线程的环境下使用,不然它只满足监控或估算的目的,在项目中 (多环境下)使用它是无法准确返回的当有太多的散列碰撞时,该表会动态增长再散列 (扩容) 是一件非常耗费资源的
2020-08-06 22:47:22
118
原创 力扣146题——LRU缓存机制
运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。 写入数据put(key, value) -如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。进阶:你是否可以在 O(.
2020-08-05 19:59:35
330
原创 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
86
原创 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
111
原创 JavaSE(8)——HashMap源码
HashMap源码解析1 Hash的来由1.1 数组的优劣势优势检索速度快按索引遍历方便能存储大量数据劣势占用空间多,浪费数组大小固定,一经确定不能改变只能存储一种类型的数据增加删除效率低1.2 链表的优劣势优势增删元素效率高内存利用率高,不浪费内存大小不固定,拓展灵活劣势检索需要遍历节点,效率低1.3 整合两种数据结构的优势散列表散列表,又叫哈希表(Hash Table),是能够通过给定的关键字的值直接访问到具
2020-08-04 16:55:42
104
原创 JavaSE(7)——红黑树的实现
红黑树左旋: p p | | X y / \ ====> / \ lx y x ry / \ / \ ly ry lx ly 红黑树右旋: p p | | y
2020-08-02 23:54:51
135
原创 JavaSE(6)——Map集合
Map集合1. Map介绍1.1 为什么需要MapSet集合是为了存储对象,快速查找而产生的,类似对象数组。而Map不同,Map的结构在官方的解释中被称为——“映射”。映射的模型是一个Key对应一个Value,用Key来区别不同的Value。比如,作为学生来说,根据学号可以区分不同的学生,只要知道学号,就可以获取对应的学生信息。比如身份证,通过身份证(key)就可以证明自己(value)。1.2 Map与Collection的区别Map集合的特点:将键映射到值的对象,一个映射不能包含重复的键,
2020-08-01 17:07:11
112
原创 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
164
原创 JavaSE(4)——Collection集合
java中的集合(Collection)1. 为什么需要Collectionjava是面向对象的语言,需要对对象进行一系列操作为了操作一堆对象,就需要把这么多对象存储起来存储时就需要一个装对象的容器因此,JDK中提供了集合(Collection)来处理若干对象2. 数组和集合的区别长度区别数组长度固定集合长度可变化内容不同数组中只能存储同一种类型的元素集合可以存储不同类型的元素(一般情况下只存相同类型元素)元素数据类型数组中可以存基本数据
2020-07-31 18:17:34
120
原创 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 <
2020-07-28 18:58:11
96
原创 JavaSE(2)——运算符
java的运算符java的运算符和C++用法基本相同,分别有算术、赋值、关系、逻辑、位和三元运算符算术运算符运算符含义+加运算-减运算*乘运算/除运算%取余运算++在当前基础上加一(符号在前时先加后使用,反之则先使用后增加)–在当前基础上减一(符号在前时先加后使用,反之则先使用后增加)赋值运算符运算符含义=将等号后面的值赋值给等号左边的变量+=使等号左边的变量值加上等号右边的值-=使等号
2020-07-26 12:36:46
132
原创 JavaSE(1)——基本数据类型和引用数据类型
java的数据类型java中数据类型分为两类,一类是基本数据类型,一类是引用数据类型基本数据类型java中一共有八种基本类型,其中有4种整型,两种浮点型,一种字符类型和一种存储真值的boolean类型1. 整型(byte,short,int,long)数据类型存储位数取值范围byte1字节-128~127(±2的7次方)short2字节-32768~32767(±2的15次方)int4字节-2147483648~2147483647(±2的31次方,正
2020-07-21 20:47:47
105
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人