
java基础
欧皇小德子
这个作者很懒,什么都没留下…
展开
-
Java基础 -> Sychronized和ReentrantLock的区别
Sychronized和ReentrantLock的区别ReentrantLock是⼀个类 ,sychronized是⼀个关键字,作为关键字,我们是没有办法过多干预的,就拿来就用,不用想那么多sychronized会⾃动的加锁与释放锁,ReentrantLock需要程序员⼿动加锁与释放Lock锁会忘记释放啊什么什么鬼的在JDK版本比较低的时候Lock锁的效率还会高一点都是现在大家都用1.8了,sychronized也有偏向锁和轻量锁了,所以sychronized确实好用sychroni原创 2022-03-03 19:44:56 · 222 阅读 · 0 评论 -
Java基础 -> Sychronized的偏向锁、轻量级锁、重量级锁
Sychronized的偏向锁、轻量级锁、重量级锁Synchronized很多人都会称呼它为重量级锁但是随着JDK 6对Synchronized进行了各种优化之后,有些情况下它并不那么重了JDK 6中为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁简单说就是,线程创建都是操作系统才能完成的阻塞和唤醒这两个步骤也都是需要操作系统去进行,很消耗资源偏向锁和轻量级锁就不再有阻塞和唤醒的步骤了,不使用操作系统程序自己完成偏向锁:在锁对象的对象头中记录⼀下当前获取到该原创 2022-03-03 19:11:18 · 277 阅读 · 0 评论 -
Java基础 -> 独享锁 VS 共享锁
独享锁 VS 共享锁独享锁和共享锁同样是一种概念。独享锁也叫排他锁,是指该锁一次只能被一个线程所持有。如果线程T对数据A加上独享锁后,则其他线程不能再对A加任何类型的锁。获得独享锁的线程即能读数据又能修改数据。JDK中的synchronized和JUC中Lock的实现类就是互斥锁 -> 独享锁。共享锁是指该锁可被多个线程所持有。如果线程T对数据A加上共享锁后,则其他线程只能对A再加共享锁,不能加排它锁。获得共享锁的线程只能读数据,不能修改数据。独享锁与共享锁也原创 2022-03-03 19:07:23 · 543 阅读 · 0 评论 -
Java基础 -> CountDownLatch丶CyclicBarraer和Semaphore的区别和底层原理
CountDownLatch丶CyclicBarraer和Semaphore的区别和底层原理CountDownLatch表示计数器,可以给CountDownLatch设置⼀个数字,CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。调⽤await()⽅法的线程会利⽤AQS排队,⼀个线程调⽤ CountDownLatch的await()将会阻塞加入阻塞队原创 2022-03-03 17:27:42 · 287 阅读 · 0 评论 -
Java基础 -> ReentrantLock中tryLock()和lock()⽅法的区别
ReentrantLock中tryLock()和lock()⽅法的区别tryLock()表示尝试加锁,可能加到,也可能加不到,该⽅法不会阻塞线程,如果加到锁则返回 true,没有加到则返回false这个方法可以选择一个参数,表示超时时间可以用这个方法搞一个获取锁的时间期限,避免死锁用循环来设置while (lock.tryLock()) { //时间控制,延时函数}lock.unlock();lock()表示阻塞加锁,线程会阻塞直到加到锁,⽅法也没有返回值lock.l原创 2022-03-03 14:41:38 · 566 阅读 · 0 评论 -
Java基础 -> 谈谈你对AQS的理解,AQS如何实现可重⼊锁?
谈谈你对AQS的理解,AQS如何实现可重⼊锁?AQS是⼀个JAVA线程同步的核心组件。是JDK中很多锁⼯具的核心组件。在AQS中,维护了⼀个信号量state和⼀个线程组成的双向链表队列。其中,这个线程队列,就是⽤来给线程排队的⽽state就像是⼀个红绿灯,⽤来控制线程排队或者放⾏的。这个加锁的过程,直接就是用CAS操作将state值从0变为1。预计为0,修改+1如果是同一个线程,多次加锁state就会叠加,不会出现死锁在可重⼊锁这个场景下,state就⽤来表示加锁的原创 2022-03-02 23:37:13 · 837 阅读 · 0 评论 -
Java基础 -> ReentrantLock中的公平锁和⾮公平锁的底层实现
ReentrantLock中的公平锁和⾮公平锁的底层实现公平锁:多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁。非公平锁:多个线程去获取锁的时候,会直接去尝试获取,获取不到,再去进入等待队列,如果能获取到,就直接获取到锁。⾸先不管是公平锁和⾮公平锁,它们的底层实现都会使⽤AQS来进⾏排队公平锁和⾮公平锁都是进入的同一个队列它们的区别在于:线程在使⽤lock()⽅法加锁时如果是公平锁,会先检查AQS队列中是否存在线程在排队如果原创 2022-03-02 23:15:10 · 363 阅读 · 0 评论 -
Java基础 -> 可重⼊锁
可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁简单理解就是:如果你拿到了锁1,接下来代码块又要拿一次锁1,你之前已经拿过锁1了,下面的也可以拿到synchronized (this) { System.out.println("第1次,锁是:" + this); //嵌套锁1 -> 此时是可以重复获得的,这就是可重入 synchronized (this) { System.out.println("第2次,锁是:" + ..原创 2022-03-02 22:26:29 · 159 阅读 · 0 评论 -
Java基础 -> 线程池中线程复⽤原理
线程池中线程复⽤原理当我们每调用execute丶submit方法的时候,就是把一个任务推到线程池就是把一个run方法推到线程池,线程池会根据情况直接执行这个方法还是加入阻塞队列当有空闲线程的时候,这个空闲线程去执行run方法,或者去阻塞队拿一个run方法出来调用原理其实就是,我们提交的任务就是一个普通的run方法线程池里面的空闲线程去执行我们提交的run方法...原创 2022-03-02 21:20:18 · 91 阅读 · 0 评论 -
Java基础 -> 线程池中阻塞队列的作⽤?为什么是先添加列队⽽不是先创建最⼤线程?
线程池中阻塞队列的作⽤?为什么是先添加列队⽽不是先创建最⼤线程?线程池中阻塞队列的作⽤阻塞队列可以保留一些没办法立即执行的任务当阻塞队列没有任务时阻塞获取任务的线程、使其进入wait状态,释放CPU资源如果线程池最低有10个线程,当阻塞队列没有任务,空闲的线程会阻塞不会出现10个线程就算没任务也保留在后台,浪费资源为什么是先添加列队⽽不是先创建最⼤线程?这个我不是很清楚,网上都说是在创建新线程的时候,是要获取全局锁的,这个时候其它的就得阻塞,影响了整体效率。应原创 2022-03-02 21:08:44 · 796 阅读 · 0 评论 -
Java基础 -> 线程池的底层⼯作原理
线程池的底层⼯作原理线程池内部是通过队列+线程实现的,当我们利⽤线程池执⾏任务时:如果此时线程池中的线程数量⼩于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。线程池最少也要保留制定的线程数量如果此时线程池中的线程数量等于corePoolSize,但是缓冲队列workQueue未满,那么任务被放⼊缓冲队列。工作队列未满,多出来的任务要先加入工作队列如果此时线程池中的线程数量⼤于等于corePoolSize,缓冲队列workQ原创 2022-03-02 19:07:08 · 276 阅读 · 1 评论 -
Java基础 -> 为什么⽤线程池?线程池的创建?
为什么⽤线程池?线程池的创建?为什么⽤线程池?随着系统越来越大丶业务越来越复杂,就需要多线程来配合工作,提升系统的性能创建一个线程的方法网上说有好几种实现runnable丶callable丶继承Thread类实际上看起来就只有一种就是new 一个Thread线程对象,那两个接口仅仅只是用来重写run方法实现业务逻辑的所以线程最基础的步骤就是创建一个线程对象,就是线程生命周期的第一步,创建状态就跟数组有工具类丶集合有工具类一样,线程为了简化步骤,肯定有自己的工具类就是线程池,线程原创 2022-03-02 18:37:18 · 168 阅读 · 0 评论 -
Java基础 -> 如何理解volatile关键字
如何理解volatile关键字变量对所有线程总是可⻅的保证被volatile修饰的共享变量对所有线程总是可⻅的,也就是当⼀个线程修改了⼀个被volatile修饰共享变量的值,新值总是可以被其他线程⽴即得知。因为cpu执行一般来说是有缓存的,一级二级三级缓存之后才到真正的内存对一个变量进行修改,会先走一级 -> 二级 -> 三级再到内存的步骤所以不会直接修改到内存的值如果要⽴即看到值的修改就禁用缓存或者跳过缓存直接修改内存中的数据volatile可以简单的理解为,对原创 2022-03-01 23:10:59 · 208 阅读 · 0 评论 -
Java基础 -> Java死锁如何避免?
Java死锁如何避免?造成死锁的⼏个原因:⼀个资源每次只能被⼀个线程使⽤⼀个线程在阻塞等待某个资源时,不释放已占有资源⼀个线程已经获得的资源,在未使⽤完之前,不能被强⾏剥夺若⼲线程形成头尾相接的循环等待资源关系这是造成死锁必须要达到的4个条件,如果要避免死锁,只需要不满⾜其中某⼀个条件即可。⽽其中前3 个条件是作为锁要符合的条件所以要避免死锁就需要打破第4个条件,不出现循环等待锁的关系。这样记忆没有意义,所以换一种记忆的方式,锁的特点加锁的资源只能同时被一个原创 2022-03-01 23:00:46 · 2243 阅读 · 0 评论 -
Java基础 -> 并发的三⼤特性
并发的三⼤特性原⼦性 丶可⻅性 丶有序性原⼦性一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。并发的原⼦性是线程对一个数据进行操作,要么线程完成数据整个流程的操作,要么这个线程对这个数据一步都不操作。关键字:synchronizedsynchronized可以保证线程对一个数据操作流程的完整性,即原⼦性可⻅性当多个线程访问同⼀个变量时,⼀个线程修改了这个变量的值,其他线程能够⽴即看得到修改的值。为什么会出现可⻅性的问题?因为cpu执行一般来原创 2022-03-01 20:13:08 · 289 阅读 · 0 评论 -
Java基础 -> 并发、并⾏、串⾏之间的区别
并发、并⾏、串⾏之间的区别串⾏在时间上不可能发⽣重叠,前⼀个任务没搞定,下⼀个任务就只能等着单线程,一个任务完全完成后再下一个任务并⾏在时间上是重叠的,两个任务在同⼀时刻互不⼲扰的同时执⾏。真正意义的多线程同时运行并发允许两个任务彼此⼲扰。统⼀时间点、只有⼀个任务运⾏,交替执⾏类似轮询机制,不同任务轮询执行,不用等待任务完全完成后再执行另一个...原创 2022-03-01 18:42:38 · 441 阅读 · 0 评论 -
Java基础 -> ThreadLocal的底层原理
ThreadLocal的底层原理ThreadLocal简介ThreadLocal是一个线程级别的局部变量,内部使用Map结构保存数据它的作用更多的是包装数据到线程中,相当于线程任何位置都可以用this可以获取这个数据在线程执行方法的时候,不用每次都显示的制定一个参数位置用来传递对象,而是用线程中的ThreadLocal来获取对象private static final ThreadLocal threadLocal = new ThreadLocal();main(){原创 2022-03-01 18:15:37 · 345 阅读 · 0 评论 -
Java基础 -> 对守护线程的理解
对守护线程的理解守护线程本质就是相对于正常线程的工具线程,用于辅助正常线程的执行的线程,为其他线程提供服务的线程超时检测守护线程丶常说的垃圾回收线程丶计时器线程丶定时任务线程等等为其他线程提供服务的线程一般来说我们工作中都不会去写这个什么守护线程因为一个守护线程是服务与所有用户线程的,我们一般来说是不能随意说想写就写的如果写了这个守护线程,它可能一直在后台运行随便来个人就去写什么守护线程,这可能会非常影响系统的性能并不是说,我有个需求,我想给这个需求搞个守护线程,你就直接搞个就完事了原创 2022-02-28 22:57:09 · 148 阅读 · 0 评论 -
Java基础 -> Thread和Runable的区别
Thread和Runable的区别Runable是一个接口,是整个线程中最顶级的一个规范,用于在线程中实现我们的业务逻辑Thread是Runable的一个实现类,用于整个线程生命周期的第一步,插件状态,也就是创建线程对象每一个线程都必须要有业务逻辑,也就是业务代码Runable接口就是一个给规范,规定了线程必须实现这个接口,因为线程必须要有业务逻辑当然JDK 1.5的时候还有一个callable接口,作用也是类似的而整个线程的生命周期中,第一步是创建一个线程对象Th原创 2022-02-28 22:24:55 · 190 阅读 · 0 评论 -
Java基础 -> 对线程安全的理解
对线程安全的理解线程安全: 多线程在并发情况下操作共享数据是否可以得到我们想要的结果线程安不安全,就是共享数据会不会因为多线程并发得不到正确的答案怎么保证共享数据的安全性?栈是每个线程独有的,所以线程安全问题不用考虑栈丶本地方法丶程序计数器。堆是共享内存,可以被所有线程访问,⼏乎所有的对象实例以及数组都在这⾥分配内存。所有线程都可以访问到该区域,这就是造成线程安全问题的潜在原因。怎么保证线程安全呢?当然就是加锁了synchronized使得操作共享对象的时候,会产生类似轮询机制的原创 2022-02-28 21:55:30 · 2999 阅读 · 0 评论 -
Java基础 -> 为什么 char 数组比 Java 中的 String 更适合存储密码?
为什么 char 数组比 Java 中的 String 更适合存储密码?由于字符串在 Java 中是不可变的,如果你将密码存储为纯文本,它将在内存中可用,直到垃圾收集器清除它.我们应该要加密一下这个密码,重新保存一个加密后的,但是字符串不可变的原因,就算改了,之前的密码依旧在内存中有一段时间存活并且为了可重用性,会存在 String 在字符串池中, 它很可能会保留在内存中持续很长时间,从而构成安全威胁。String 在字符串池会获得比我们想象的更加久,这对密码来说是有安全隐患的原创 2022-02-28 00:22:04 · 632 阅读 · 0 评论 -
Java基础 -> 为什么Java中不支持多重继承?
为什么Java中不支持多重继承?多重继承是从哪里来的?C++C++有多重继承,可以继承很多类,但是C++没有接口Java没有多重继承,但是java有继承 + 接口Java 只能继承一个类,因为Java是面向对象语言,一个类可继承的属性不应该来自多个类,继承是类与类的关系,在Java中是对本身更高层次的抽象,而不是更多层次的抽象,不是人丶猫丶狗这样去抽象,而是人丶动物这样的抽象方式所以Java的思想就不支持多重继承,但是支持对象的扩展,也就是接口多重继承既可以实现更高层次的抽象又可以原创 2022-02-27 23:33:44 · 3856 阅读 · 0 评论 -
Java基础 -> 为什么wait需要依赖synchronized关键字
为什么wait需要依赖synchronized关键字答案: synchronized的作用是给对象加锁wait丶notify需要一下加锁的对象状态这个问题其实跟为什么wait 是 Object 类的本地方法?是一个道理我们要知道wait丶notify是用来线程通信的而什么叫做线程通信?是我们多个线程完成一个任务的时候,需要线程互相协作,一个线程通知另外一个指定线程开始工作所以线程通信要通信什么?线程之间什么是两个线程共有的,用这个共有的东西,去控制是该执行这个原创 2022-02-27 21:11:26 · 764 阅读 · 0 评论 -
Java基础 -> 为什么wait 是 Object 类的本地方法
为什么wait 是 Object 类的本地方法本质上来说wait 和 notify 是用于两个线程通信的,不是单纯用来让一个线程等待,或者唤醒一个线程它从一开始出现就不是单单为了去阻塞一个线程的,为了用于线程通信而什么叫做线程通信?线程是相互独立的,但是我们需要多个线程完成一个任务的时候,需要线程直接互相协作比如操作同一份数据,线程1操作了第一部分,线程2要接着操作第二部分这就是线程之间的通信所以线程通信要通信什么?答:要通信数据,数据是什么,数据是线程吗?不,数据是对象有这么原创 2022-02-27 19:21:26 · 928 阅读 · 0 评论 -
Java基础 -> sleep()、wait()、join()、yield()之间的的区别
sleep()、wait()、join()、yield()之间的的区别内部锁每个对象都有内部锁,内部锁会维护两个集合结构Entry Set(网上有叫锁池): 多个线程抢锁,没抢到的线程加入锁池(Entry Set)Wait Set(网上有叫等待池): 调用wait⽅法阻塞的线程,会加入这个等待池Wait Set一个线程只能加入锁池或者等待池,线程不管加入哪个池,都代表此时已经不在持有锁了没抢到锁的,不持有锁,调用wait方法的也不持有锁sleep 是 Thread 类的静态本原创 2022-02-27 17:29:08 · 551 阅读 · 0 评论 -
Java基础 -> 线程的生命周期?线程有几种状态?
线程的生命周期?线程有几种状态?线程通常有五种状态,创建,就绪,运⾏、阻塞和死亡状态:创建状态(New):新创建了⼀个线程对象。仅仅是线程对象,操作系统线程还没有创建关键操作: new Thread();就绪状态(Runnable):线程对象创建后,其他线程调⽤了该对象的start⽅法。该状态的线程位于 可运⾏线程池中,变得可运⾏,等待获取CPU的使⽤权。操作系统创建线程,线程进入CPU队列,等待获取CPU的使⽤权关键操作: start();运⾏状态(Running)原创 2022-02-27 15:22:34 · 318 阅读 · 0 评论 -
JVM基础 -> JVM参数有哪些?
JVM参数有哪些?1. 堆参数-Xms: 初始化堆内存-Xmx: 最大堆内存-Xmn: 设置新生代内存,剩余的为老年代的2. 回收器参数-XX:Use收集器名称SerialGC丶ParallerGC丶ParallerOldGC丶ConcMarkSweep丶G1GC原创 2022-02-26 17:06:30 · 169 阅读 · 0 评论 -
JVM基础 -> 三⾊标记
三⾊标记三⾊标记:是⼀种逻辑上的抽象,是一种分析工具,理解可达性分析法是怎么分析对象是否可以被回收用的。将每个内存对象分成三种颜⾊:⽩⾊:⾃⼰未标记完。灰⾊:⾃⼰标记完了,但是成员变量还没有完全标记完。⿊⾊:表示⾃⼰和成员变量都已经标记完毕。大致步骤开始之前,将所有对象都标记为白色分析开始,将GC roots对象标记为黑色,黑色的下一个会被染色灰色,表示下次分析分析到灰色,将灰色变成黑色,将灰色的下一个染成灰色以此类推,知道走完所有引用链,扫描完原创 2022-02-26 16:58:55 · 452 阅读 · 0 评论 -
JVM基础 -> G1垃圾收集器
说说G1垃圾收集器G1概览G1 GC 全称是Garbage First Garbage Collector,垃圾优先垃圾回收器,以下简称G1。G1是HotSpot JVM的短停顿垃圾回收器。其实关于G1的论文早在2004年就有了,但是G1是在2012年4月发布的JDK 7u4中才实现。从长期来说,G1旨在取代CMS(Concurrent Mark Sweep)垃圾回收器。G1从JDK9开始已经作为默认的垃圾回收器。如果对于应用程序来说停顿时间比吞吐量更重要,G1是非常合适原创 2022-02-26 16:13:58 · 450 阅读 · 0 评论 -
JVM基础 -> CMS垃圾收集器
CMS收集器CMS全称Concurrent Mark Sweep,是一款并发的、主要使用标记-清除算法的垃圾回收器,该回收器是针对老年代垃圾回收的,在初始化阶段会导致STW。这里有一个重点: 主要标记-清除算法的垃圾回收器不是标记-整理算法 -> 说明会出现很多内存间隙,也就是内存碎片其实CMS会根据一个系统参数判定多少次垃圾回收之后执行不一样的FullGCFullGC停下当前所有的用户线程,开启单线程Serial收集器对于老年代的内存碎片进行整理,使用的标记-整理算法。不再推原创 2022-02-25 19:46:41 · 893 阅读 · 0 评论 -
JVM基础 -> GC分代: MinorGC MajorGC FullGC Mixed GC
GC分代: MinorGC MajorGC FullGC Mixed GCMinorGC 也叫新生代GC:发生在新生代的垃圾回收,因为新生代的特点,MinorGC非常频繁,且回收速度比较快,每次回收的量也很大。注意: 新生代GC是一个形容词例如,你要打扫一下卧室垃圾,卧室GC是一个形容词,利用什么打扫,用什么方式是另一个问题新生代GC完成GC,用指定好的垃圾回收器,垃圾回收器会有自己的回收算法当然,MinorGC的垃圾回收器一定是用复制算法,他没有别的算法的选择MajorGC原创 2022-02-25 17:58:03 · 636 阅读 · 0 评论 -
Java基础 -> GC日志分析
GC日志分析GC日志是一个很重要的工具,它准确记录了每一次的GC的执行时间和执行结果,通过分析GC日志可以调优堆设置和GC设置,或者改进应用程序的对象分配模式,开启的JVM启动参数如下:-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps常见的Young GC、Full GC日志含义如下:![]](https://img-blog.csdnimg.cn/9003961e884e41d09原创 2022-02-25 17:54:45 · 475 阅读 · 0 评论 -
JVM基础 -> JVM有哪些垃圾回收器?
JVM有哪些垃圾回收器?并不是都要去学,更多的都是历史收集器,被淘汰了的只需要了解一下现在和上一个阶段使用的收集器即可第一阶段: Serial (串行) 收集器 -> 时间在JDK1.3左右新⽣代(Serial—复制算法) ⽼年代(SerialOld—标记-整理算法) -> 开启配置如下 ↓-XX:+UseSerialGC第二阶段: Parallel (并行) 收集器 -> JDK 6中才开始提供,JDK 6中默认使用Parallel收集器也称吞吐量收原创 2022-02-25 17:51:02 · 144 阅读 · 0 评论 -
JVM基础 -> 什么是STW?
什么是STW?STW: Stop-The-World: 是在垃圾回收算法执⾏过程当中,将JVM内存冻结丶应用程序停顿的⼀种状态。在STW 状态下,JAVA的所有线程都是停⽌执⾏的 -> GC线程除外一旦Stop-the-world发生,除了GC所需的线程外,其他线程都将停止工作,中断了的线程直到GC任务结束才继续它们的任务。STW是不可避免的,垃圾回收算法执⾏一定会出现STW,我们要做的只是减少停顿的时间GC各种算法优化的重点,就是减少STW(暂停),同时这也是JVM调优的重点。原创 2022-02-23 21:54:01 · 14609 阅读 · 0 评论 -
JVM基础 -> JVM有哪些垃圾回收算法?
JVM有哪些垃圾回收算法?可达性分析法标记清除算法拷⻉算法标记压缩算法分代收集算法垃圾回收会经历两个阶段:标记可回收对象阶段 -> 可达性分析法垃圾清除阶段 -> 标记清除算法 拷⻉算法 标记压缩算法 分代收集算法标记可回收对象阶段标记可回收对象阶段使用的算法是可达性分析法可达性分析法: 从 GC Roots 开始向下搜索,搜索所⾛过的路径称为引⽤链。当⼀个对象到 GC Roots 没有任何引⽤链相连时,则证明此对象是不可⽤的,那么虚拟机就判断是可回原创 2022-02-23 18:08:21 · 404 阅读 · 0 评论 -
JVM基础 -> ⼀个对象从加载到JVM,再到被GC清除,都经历了什么过程?
⼀个对象从加载到JVM,再到被GC清除,都经历了什么过程?⾸先类加载器把字节码⽂件内容加载到⽅法区,当然类加载器这中间用双亲委派机制加载然后再根据加载完方法区中的类信息在堆区为对象分配内存丶初始化零值丶设置对象头丶执行 init 方法分配内存: 确定大小的内存从 Java 堆中划分出来初始化零值: 将分配到的内存空间都初始化为零,这样对象只定义,不初始化也可以用设置对象头: 对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等执行 init 方法: 最后就是原创 2022-02-22 23:52:45 · 907 阅读 · 0 评论 -
JVM基础 -> 你们项目如何排查JVM问题
你们项目如何排查JVM问题对于还在正常运⾏的系统:通过各个命令的结果,或者jvisualvm等⼯具来进⾏分析可以使⽤jmap来查看JVM中各个区域的使⽤情况可以通过jstack来查看线程的运⾏情况,⽐如哪些线程阻塞、是否出现了死锁可以通过jstat命令来查看垃圾回收的情况,特别是fullgc,如果发现fullgc⽐较频繁,那么就得进⾏调优了⾸先,初步猜测频繁fullgc(整体大面积垃圾回收)的原因如果频繁发⽣fullgc但是⼜⼀直没有出现内存溢出,系统运行的好好原创 2022-02-22 22:51:43 · 1067 阅读 · 0 评论 -
JVM基础 -> JVM中哪些是线程共享区
JVM中哪些是线程共享区堆区和⽅法区是所有线程共享的,栈、本地⽅法栈、程序计数器是每个线程独有的堆: 不用多说了,放对象的地方方法区: 类定义的成员变量丶常量丶静态变量丶方法都在这里栈: 程序运行才有的,会把运行时的方法压入栈,里面有局部变量等东西本地方法栈: 操作系统方法程序计数器: 标记代码走到哪里了...原创 2022-02-22 18:22:59 · 4197 阅读 · 0 评论 -
JVM基础-> GC如何判断对象可以被回收
GC如何判断对象可以被回收引⽤计数法(已被淘汰):每个对象有⼀个引⽤计数属性,新增⼀个引⽤时计数加1,引⽤释放时计数减1,计数为0时可以回收目前主流的java虚拟机都摒弃掉了这种算法,最主要的原因是它很难解决对象之间相互循环引用的问题。尽管该算法执行效率很高。可达性分析法:从 GC Roots 开始向下搜索,搜索所⾛过的路径称为引⽤链。当⼀个对象到 GC Roots 没有任何引⽤链相连时,则证明此对象是不可⽤的,那么虚拟机就判断是可回收对象。目前主流的编程语言(java,C#等)的主原创 2022-02-22 17:52:22 · 485 阅读 · 0 评论 -
JVM基础 -> 说说类加载器双亲委派模型
说说类加载器双亲委派模型双亲委派机制: 如果一个类加载器收到类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类(双亲)加载器完成。JVM中存在三个默认的类加载器:BootstrapClassLoader -> 根类加载器ExtClassLoader -> 扩展类加载器AppClassLoader -> 系统类加载器首先判断该类之前是否已加载,逐级向父类判断之前是否加载,之前加载过就结束若之前都没加载,则传自顶向下调用双亲加原创 2022-02-22 17:04:04 · 262 阅读 · 0 评论