技术# Java Core
文章平均质量分 76
记录Java Core相关知识
summer_west_fish
本科毕业深圳大学,拥有Java开发10年的经验。 拥有Devops、敏捷和项目管理多年的经验,并且获得PMP、ACP和DOP等相关证书。
展开
-
java程序cpu飙高如何排查
如何使用原生top命令、jstack命令来做定位具体代码的位置处理toptop -Hp 7当然更常见的是我们对整个 jstack 文件进行分析,通常我们会比较关注 WAITING 和 TIMED_WAITING 的部分,BLOCKED 就不用说了。原创 2024-01-22 14:53:58 · 1210 阅读 · 0 评论 -
JVM 对象动态年龄判断
JVM 对象动态年龄判断是怎么回事?虚拟机并不是永远地要求对象年龄必须达到了-XX:MaxTenuringThreshold=15才能晋升老年代;动态年龄判断: Survivor区的对象年龄从小到大进行累加,当累加到X年龄(某个年龄)时占用空间的总和大于50%(可以使用-XX:TargetSurvivorRatio=?来设置保留多少空闲空间,默认值是50),那么比X年龄大的对象都会晋升到老年代;...原创 2021-06-10 10:06:02 · 2100 阅读 · 7 评论 -
Java对象结构
一、对象结构在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。下图是普通对象实例与数组对象实例的数据结构:对象头HotSpot虚拟机的 对象头 包括两部分信息:markword第一部分markword,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)原创 2021-03-08 10:19:05 · 192 阅读 · 0 评论 -
可达性算法之GCRoots
Java GC RootsJava中的GCRoot虚拟机栈中引用的对象方法区类的静态成员引用的对象方法区常量引用的对象本地方法栈中JNI引用的对象Java中的GCRoot哪些对象可作为GCRoots对象呢? 包括如下:虚拟机栈帧上本地变量表中的引用对象(方法参数、局部变量、临时变量)方法区中的静态属性引用类型对象、常量引用对象本地方法栈中的引用对象(Native方法的引用对象)Java虚拟机内部的引用对象,如异常对象、系统类加载器等所以被同步锁(synchronize)持有的对象Java虚原创 2021-04-02 15:25:07 · 474 阅读 · 0 评论 -
Parallel Scavenge收集器
Parallel Scavenge 特点Parallel Scavenge收集器是一个新生代收集器,它也是使用【标记-复制】算法的收集器,并且并行的多线程收集。CMS收集器关注点是尽可能地缩短垃圾收集时用户线程的停顿时间停顿时间越短就越适合需要与用户交互的程序,良好的响应速度能提升用户体验。Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)吞吐量是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运原创 2021-05-31 09:48:52 · 424 阅读 · 0 评论 -
JVM垃圾收集器
JVM垃圾收集器垃圾收集器-XX:+UseSerialGC-XX:+UseParNewGC-XX:+UseParallelGC-XX:+UseParallelOldGC-XX:+UseConcMarkSweepGC-XX:+UseG1GC垃圾回收器作用区域垃圾收集器配合垃圾收集器-XX:+UseSerialGC新生代和老年代都使用串行收集器串行收集器使用单线程并且是独占式的垃圾回收-XX:+UseParNewGC新生代使用ParNew垃圾回收器,老年代使用串行收集器ParNew是串行收集器的原创 2020-11-26 12:34:45 · 364 阅读 · 1 评论 -
Linux环境变量设置
Linux环境变量设置原创 2023-01-30 17:37:03 · 1769 阅读 · 0 评论 -
Java垃圾回收算法
Java垃圾回收算法原创 2020-11-21 00:03:42 · 215 阅读 · 0 评论 -
Java 服务内存占用太高
对于大多数服务端场景来说,并不需要JVM 这个手动释放内存的操作。至于 JVM 是否归还内存给操作系统这个问题,我们也并不关心。而且基于上面那个测试结果,不同 JAVA 版本,不同垃圾回收器版本区别这么大,更是没必要去深究了。综上,JVM 虽然可以释放空闲内存给操作系统,但是不一定会释放,在不同 JAVA 版本,不同垃圾回收器版本下表现不同,知道有这个机制就行。原创 2023-01-23 17:59:34 · 5471 阅读 · 2 评论 -
JVM堆OOM后其它线程是否可以继续工作
123转载 2021-07-27 10:36:25 · 171 阅读 · 0 评论 -
实战:JVM垃圾回收
在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。堆大小 = 新生代 + 老年代。其中,堆的大小可以通过参数 –Xms、-Xmx 来指定。......原创 2022-08-05 14:20:40 · 231 阅读 · 0 评论 -
Java中枚举的线程安全性及序列化问题
要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和class一样,只是一个关键字,他并不是一个类,那么枚举是由什么类维护的呢,我们简单的写一个枚举:然后我们使用反编译,看看这段代码到底是怎么实现的,反编译后代码内容如下:通过反编译后代码我们可以看到,,说明,该类是继承了Enum类的,同时final关键字告诉我们,这个类也是不能被继承的。当我们使用来定义一个枚举类型的时候,编译器会自动帮我们创建一个final类型的类继承Enum类,所以枚举类型不能原创 2022-06-17 14:01:19 · 628 阅读 · 0 评论 -
Java21 虚拟线程
虚拟线程是一种轻量化的线程封装,由jvm直接调度和管理。反之普通的线程其实是调用的操作系统的能力,对应的是操作系统级的线程。相对虚拟线程来说操作系统级的线程持有成本很高,而且受操作系统调度和管理的。实际在普通多线程情况下,如果出现IO阻塞,这个线程就必须得跟着阻塞,这个线程对应的操作系统就被阻塞,而他却持有大量的内存。另外,要处理大量的IO就得新建更多线程,而大量的线程会在操作系统切换时因上下文切换导致大量的CPU被浪费。原创 2023-09-26 11:40:38 · 1211 阅读 · 1 评论 -
Java17稳妥升级计划
近年来,微服务、容器化、云原生等基础设施或架构设计不断更新迭代,对Java技术体系带来新的挑战,同时也迫使Java加快了更新步伐以适应新的环境与需求。目前许多企业仍将Java 8作为首选的信息系统开发编程语言,然而我们必须注意到,Java 8已经面临支持结束的阶段。在这个时间节点上,我们应认真考虑Java 17升级计划,做好必要的调研与对策。持续迭代更新,是开源软件能保持生命力的重要原因。原创 2023-04-04 10:21:30 · 1110 阅读 · 0 评论 -
Linux管道、标准输入输出
默认Linux的命令的结果都是输出到标准输出,错误信息 (比如命令未找到或文件格式识别错误等) 输出到标准错误,而标准输出和标准错误默认都会显示到屏幕上。管道符,表示把前一个命令的输出作为后一个命令的输入,前面也有一些展示例子。标准输入,后面可以跟可以产生输出的命令,一般用于1个程序需要多个输入的时候。>, |, -,在我们处理输入和输出时存在重要但具有迷惑性的作用。(短横线):表示标准输入,一般用于1个程序需要多个输入的时候。表示把标准错误重定向到标准输出。在Linux系统中,有4个特殊的符号,原创 2022-12-22 22:38:03 · 1102 阅读 · 0 评论 -
操作系统信号机制
当然了发 kill 信号必须具有一定的权限,否则任意进程都可以通过发信号来终止其他进程,那显然是不合理的,实际上 kill 执行的是系统调用,将控制权转移给了内核(操作系统),由内核来给指定的进程发送信号。说到这大家是否想起了一道经典面试题:如何让正在运行的 Java 工程的优雅停机,通过上面的介绍大家不难发现,其实是。,大家想想要干掉一个正在运行的进程是不是经常用 kill -9 pid 这样的命令,这里的。线程崩溃后,进程是如何崩溃的呢,这背后的机制到底是怎样的,答案是。查看所有可用的信号。原创 2022-12-20 10:52:24 · 403 阅读 · 0 评论 -
SpringCloud OpenFeign
Feign 提供了很多的扩展机制,让用户可以更加灵活的使用。:修改日志级别,包含四种不同的级别:NONE、BASIC、HEADERS、FULL。:响应结果的解析器,http远程调用的结果做解析,例如解析json字符串为java对象。:请求参数编码,将请求参数编码,便于通过http请求发。:支持的注解格式,默认是SpringMVC的注解。:失败重试机制,请求失败的重试机制,默认是没有,不过会使用Ribbon的重试。1、日志配置可以通过配置Feign的日志级别来显示需要的日志。原创 2022-11-07 22:21:54 · 428 阅读 · 0 评论 -
SpringBoot性能优化
在开始对SpringBoot服务进行性能优化之前,我们需要做一些准备,把SpringBoot服务的一些数据暴露出来。比如,你的服务用到了缓存,就需要把缓存命中率这些数据进行收集;用到了数据库连接池,就需要把连接池的参数给暴露出来。我们这里采用的监控工具是Prometheus,它是一个是时序数据库,能够存储我们的指标。SpringBoot可以非常方便的接入到Prometheus中。创建一个SpringBoot项目后,首先,加入maven依赖。然后,我们需要在配置文件中,开放相关的监控接口。原创 2022-10-05 21:07:17 · 1367 阅读 · 0 评论 -
零拷贝技术
零拷贝如果简单用 Java 里面对象的概率来理解的话,其实就是使用的都是对象的引用,每个引用对象的地方对其改变就都能改变此对象,永远只存在一份对象。原创 2022-09-15 11:00:07 · 160 阅读 · 0 评论 -
Maven发布jar到Nexus
Maven发布jar到Nexus原创 2022-08-17 17:32:40 · 858 阅读 · 0 评论 -
Linux下运行Java Jar程序
通过几种方式的对比,能得出结论—执行jar文件用第4种方式最好,同时可以把它写成一个脚本,不用每次都写一遍。新建start.sh,根据我上传的demo.jar,输出到1.txt中,具体脚本如下:Linux下执行jar文件,一定要用nohup命令。...原创 2022-08-09 10:44:58 · 943 阅读 · 0 评论 -
CAS原理
一、核心思想CAS 涉及到以下操作:假设内存中的原数据V,旧的预期值A,需要修改的新值B。1、比较 A 与 V 是否相等。(比较)2、如果比较相等,将 B 写入 V。(交换)3、返回操作是否成功二、CAS基础实现CAS 是 compare and swap 的简写,即比较并交换。它是指一种操作机制,而不是某个具体的类或方法。在 Java 平台上对这种操作进行了包装。在 Unsafe 类中,调用代码如下:unsafe.compareAndSwapInt(this,.原创 2022-05-26 14:13:10 · 4041 阅读 · 0 评论 -
Synchronized原理
互斥锁:当一个共享数据被当前正在访问到线程添加了互斥锁之后,在同一时刻,其他线程只能等待,直到当前线程释放该锁。在多线程使用共享资源的时候, 我们可以使用synchronized来锁定共享资源。synchronized可以添加互斥锁,并且保证被其他线程看到。一、synchronized的三种应用方式synchronized关键字最主要有以下3种应用方式,下面分别介绍:修饰实例方法,作用于当前实例加锁,进入同步代码钱要获得当前实例的锁 修饰静态方法,作用于当前类对象加锁,进入同步代码前要原创 2022-05-24 16:47:23 · 210 阅读 · 0 评论 -
Monitor与重量级锁
轻量级锁和偏向锁是Java 6对synchronized锁进行优化后新增加的。重量级锁就是通常说的synchronized的对象锁,锁标识位10,其中指针指向的时monitor对象的起始地址(也称为管程或监视器锁)。每个对象都存在着一个monitor与之关联,对象与其monitor之间的关系有存在多种实现方式,如monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成,但当一个monitor被某个线程持有后,它便处于锁定状态。在Java虚拟机(HotSpot)中,monitor是原创 2022-05-24 15:26:55 · 413 阅读 · 0 评论 -
Java对象头
一、概述在 JVM 中,对象在堆内存中的布局分为三块区域:对象头、实例变量和填充数据。对象头区域Java对象的对象头由 mark word 和 class pointer 两部分组成。对象自身的运行时数据(MarkWord)。存储 hashcode、GC 分代年龄、锁类型标记、偏向锁线程 ID、CAS 锁指向线程 LockRecord 的指针等,synchronized 锁的机制与这个部分(markwork)密切相关,用 markword 中最低的三位代表锁的状态,其中一位是偏向锁位,原创 2022-05-24 14:44:42 · 1821 阅读 · 0 评论 -
Java指令重排
什么是重排序?为了提高性能,在遵守 as-if-serial 语义(即不管怎么重排序,单线程下程序的执行结果不能被改变。编译器,runtime 和处理器都必须遵守。)的情况下,编译器和处理器常常会对指令做重排序。一般重排序可以分为如下三种类型:编译器优化重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。 指令级并行重排序。现代处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。 内存系统重排序。由于处理.原创 2022-05-23 17:00:28 · 3050 阅读 · 0 评论 -
volatile关键字
使用 volatile 修饰共享变量后,每个线程要操作变量时会从主内存中将变量拷贝到本地内存作为副本,当线程操作变量副本并写回主内存后,会通过 CPU 总线嗅探机制告知其他线程该变量副本已经失效,需要重新从主内存中读取。volatile 保证了不同线程对共享变量操作的可见性,也就是说一个线程修改了 volatile 修饰的变量,当修改后的变量写回主内存时,其他线程能立即看到最新值。接下来我们就聊聊一个比较底层的知识点:总线嗅探机制。总线嗅探机制在现代计算机中,CPU 的速度是极高的,如.原创 2022-05-23 16:26:31 · 377 阅读 · 0 评论 -
Java内存模型
现代CPU构造原创 2022-05-23 15:06:48 · 121 阅读 · 0 评论 -
Java多线程
Java 中用到的线程调度算法是什么?计算机通常只有一个 CPU,在任意时刻只能执行一条机器指令,每个线程只有获得CPU 的使用权才能执行指令。所谓多线程的并发运行,其实是指从宏观上看,各个线程轮流获得CPU的使用权,分别执行各自的任务。在运行池中,会有多个处于就绪状态的线程在等待 CPU, Java虚拟机的一项任务就是负责线程的调度,线程调度是指按照特定机制为多个线程分配CPU的使用权。有两种调度模型:分时调度模型和抢占式调度模型。分时调度模型, 是指让所有的线程轮流获得 cpu 的.原创 2022-05-20 23:29:24 · 122 阅读 · 0 评论 -
Java中volatile用来做什么?
Java中volatile用来干啥?Volatile是Java虚拟机提供的轻量级的同步机制(三大特性):保证可见性 不保证原子性 禁止指令重排要理解三大特性,就必须知道Java内存模型(JMM),那JMM又是什么呢?JMM又是啥?...原创 2021-10-27 09:48:46 · 1043 阅读 · 1 评论 -
String为什么不可变
一、String源码分析String在日常开发中的使用频率相当高,所以今天就要扒开String的外衣,看看它究竟为什么?不可变性public final class String implements java.io.Serializable, Comparable<String>, CharSequence {...}从代码中可以看到,String类由final关键字修饰,这也意为着String类不可被继承,创建后不能被修改。String类同时实现了三..原创 2021-09-26 10:09:26 · 67 阅读 · 0 评论 -
LockSupport 以及 park、unpark 方法
LockSupport是 jsr 166 中新增的 juc 工具类。 LockSupport 类主要用于创建锁和其他同步类来实现线程阻塞。 这个类与他使用的每个线程进行关联, 如果可用就立即 park , 我们可以通过 unpack 方法进行唤醒。park 方法分析除非许可证可用,否则出于线程调度目的禁用当前线程。 如果许可证可用,则该许可证被消耗,呼叫立即返回;否则,出于线程调度目的,当前线程将被禁用,并处于休眠状态,直到发生以下三种情况之一:其他线程以当前线程为目标调用 unpark原创 2021-09-10 17:28:04 · 624 阅读 · 0 评论 -
Java中常见的线程同步方式
为了完成JMM的操作,完成线程之间的变量同步,Java提供了非常多的同步手段:Java的基类Object中,提供了wait和notify的原语,来完成monitor之间的同步。不过这种操作我们在业务编程中很少遇见; 使用synchronized对方法进行同步,或者锁住某个对象以完成代码块的同步; 使用concurrent包里面的可重入锁。这套锁是建立在AQS之上的; 使用volatile轻量级同步关键字,实现变量的实时可见性; 使用Atomic系列,完成自增自减; 使用ThreadLocal线原创 2021-09-10 11:57:48 · 158 阅读 · 0 评论 -
AQS实现原理
AQS中维护了一个volatile int state(共享资源)和一个CLH队列。当state=1时代表当前对象锁已经被占用,其他线程来加锁时则会失败,失败的线程被放入一个FIFO的等待队列中,然后会被UNSAFE.park()操作挂起,等待已经获得锁的线程释放锁才能被唤醒。我们拿具体场景来分析,假设同时有三个线程并发抢占锁,此时线程一抢占成功,线程二、三抢占失败,具体流程如下:此时AQS内部数据结构为:上图可以看到等待队列中的节点Node是一个双向链表,这里SIGNAL是No..转载 2021-09-03 14:12:20 · 5062 阅读 · 3 评论 -
ThreadLocal原理
源码实现一个线程内可以存多个ThreadLocal对象,存储的位置位于Thread的ThreadLocal.ThreadLocalMap变量,在Thread中有如下变量:/* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ThreadLocal.ThreadLocalMap threadLocals = null;ThreadLocalMa原创 2021-08-25 13:53:26 · 120 阅读 · 0 评论 -
Java函数式接口
函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。 这类接口只定义了唯一的抽象方法的接口,并且这类接口使用了@FunctionalInterface进行注解。在jdk8中,引入了一个新的包java.util.function, 可以使java 8 的函数式编程变得更加简便。这个package中的接口大致分为了以下四类:Function: 接收参数,并返回结果,主要方法R apply(T t) Consumer: 接收参数,无返回结果, 主要方法为voi..原创 2021-08-04 15:34:15 · 91 阅读 · 0 评论 -
LockSupport原理分析
Cas LockParker Sync区别转载 2021-03-08 17:02:14 · 614 阅读 · 1 评论 -
LinkBlockedQueue与ArrayBlockingQueue异同
mp mc 模式 多生产 多消费原创 2021-01-16 23:21:33 · 267 阅读 · 0 评论 -
JDK和SpringBoot中SPI的实现原理和区别
SPI 简介Service Provider Interface JDK内置的中服务发现机制, 一种动态替换发现的机制.使用方式写service 具体对外提供的接口public interface DriverService { String getName();}具体的实现,继承对应的接口public class JavaDriverImpl implements DriverService { @Override public String getName()原创 2021-01-13 11:46:17 · 699 阅读 · 1 评论 -
Java类加载过程
Java类加载过程原创 2020-12-26 15:42:04 · 83 阅读 · 0 评论