- 博客(210)
- 资源 (6)
- 收藏
- 关注
原创 ZGC的流程图
•转发表记录了对象从旧位置到新位置的映射关系,实现类似一个hash表,key是旧分区的位置,value是新分区的位置,此时当访问旧位置的对象时,通过转发表可以获取新位置。通过读屏障,ZGC能够在读取对象引用时,将访问重定向到新位置,以确保对象的访问仍然有效。迁移根节点直接引用的对象到新分区,这个阶段需要停顿所有的应用线程(STW),但由于只迁移根节点直接引用的对象,所以停顿时间很短。刚好下一个GC周期也要进行扫描标记,可以利用扫描标记的时间,同时把对象引用修正指向到新分区,以此提升效率,减少停顿时间。
2024-07-12 17:12:42
884
原创 ZGC在三色指针中的应用
在转移阶段,ZGC是按照页面进行部分内存垃圾回收的,也就是说当对象所在的页面需要回收时,页面里面的对象需要被转移,如果页面不需要转移,页面里面的对象也就不需要转移。ZGC初始化之后,整个内存空间的地址视图被设置为Remapped,当进入标记阶段时的视图转变为Marked0(也称为M0)或者Marked1(也称为M1),从标记阶段结束进入转移阶段时的视图再次设置为Remapped。如果应用程序线程访问在对象活跃信息表中,且视图为M0,说明对象是标记阶段标记的活跃对象,所以需要转移对象。
2024-07-08 16:08:13
1266
原创 jdk21颜色指针研究
这种技术的目的是在对象移动时,通过修改指针本身而不是对象的引用关系,来维护正确的引用关系,从而避免了对引用对象的访问和修改。在自愈指针技术中,指针的高位(通常是一些特定的位或字节)被用来存储额外的信息,例如对象的新地址、标记信息等。这样一来,垃圾标记阶段遍历的不再是对象图来标记垃圾,而是通过遍历“引用图”来标记垃圾,引用的对象便是堆中的对象。通过这四个标志位,JVM可以直接从对象的指针上获取关键的状态信息,而无需访问对象本身的其他属性,这种直接的标志位设计有助于提高垃圾收集的效率和性能。
2024-07-08 11:26:16
906
原创 java到底是值传递还是引用传递
1、一定是值传递,给你的表象也有引用传递是因为对象传递的引用地址,我们在堆里更改了对象的属性值,但是地址没有变更,所以是值传递,可以参考方法的堆栈。
2024-07-03 10:20:00
228
原创 ZGC垃圾收集的主要流程
GC Roots(例如,线程栈中引用的对象,静态变量等)为每次标记的起点,所有被 GC Roots 引用的对象都应被认为是存活的;与此同时,发现对象 2 引用了对象 5,而对象 5 的颜色是“坏的”(对象 5 的实际颜色 Marked0 与期望颜色 Remapped 不符),会基于转发表,将对象 5 的地址重映射对象 5'。值得注意的是,此时对象 2(对象 4')中记录的对象 5(对象 7)的地址仍为迁移前的地址,指针的颜色也仍为标记时的颜色 Marked0。此外,还需要将上一次 GC 的转发表删除。
2024-06-26 18:54:56
747
原创 JAVA ZGC相关GC日志详情分析
记录了 ZGC 各个阶段的耗时,其中 "Pause" 与 "Concurrent" 分别标识了 STW 阶段与并发阶段。其中 "gc*" 意为打印所有 tag 中以 "gc" 开头的日志,"gc.log" 为日志存储路径。第 1 行标志了一次 GC 的开始,是进程启动后的第 100 次(从 0 开始计数)GC,触发原因为 "Timer"。"Final":终结引用(FinalReference)。下面以 AutoMQ 在实际运行时的一次 GC 为例,按照不同的 log tag,解释 ZGC 日志的含义。
2024-06-26 18:48:23
1479
原创 GC Roots相关数据分析和示例解析
在Java虚拟机(JVM)中,垃圾收集器(Garbage Collector, GC)的GC Roots是一组对象,这些对象作为起始点,用于确定哪些对象仍然可达(即“存活”)以及哪些对象不再可达(即“垃圾”)。当进行垃圾收集时,GC会从这些GC Roots开始,遍历整个对象图,标记所有可达的对象,并回收所有不可达的对象。请注意,GC Roots的值并不是固定不变的,它们随着程序的执行而动态变化。当一个新的线程被创建时,它的栈帧中的对象会成为新的GC Roots;
2024-06-24 17:51:21
383
原创 springboot应用cpu飙升的原因排除
1、通过top或者jps命令查到是那个java进程, top可以看全局那个进程耗cpu,而jps则默认是java最耗cpu的,比如找到进程是196。5、发现196进程里的线程id:590是最耗cpu的,可以使用linux命令直接kill掉,杀死线程命令是 两个 --4、查询jstack.log相关的 ,pid为 590的值,可以查看堆栈信息,找到具体的业务代码。2、根据第一步获取的进程号,查询进程里那个线程最占用cpu,发现590消耗最多。1.1 top (推荐)或者jps命令均可。
2024-06-19 23:52:35
2083
原创 关于springboot一个接口请求后,主动取消后,后端是否还在跑
1、最近在思考一个问题,如果一个springboot的请求的接口比较耗时,中途中断该请求后,则后端服务是否会终止该线程的处理,于是写了一个demo。4、发现即使取消请求后,springboot后端还是会进行业务处理,不会自动终止的。
2024-03-06 18:23:14
2449
原创 Maven类包冲突终极三大解决技巧 mvn dependency:tree
(这一步非常重要哦,经常项目组pom.xml是相同的,但是就是有些人可以运行,有些人不能运行,俗称人品问题,其实都是IDE的缓存造成的了。这里有一个需要特别注意的,即B和C同时依赖于X,假设B依赖于X的1.0版本,而C依赖于X的2.0版本,A究竟依赖于X的1.0还是2.0版本呢?A依赖于B及C,而B又依赖于X、Y,而C依赖于X、M,则A除引B及C的依赖包下,还会引入X,Y,M的依赖包(一般情况下了,是把照妖照,pom.xml用它照照,所有传递性依赖都将无处遁形,并且会以层级树方式展现,非常直观。
2024-01-09 21:55:14
1877
原创 ZGC垃圾收集器介绍
相比G1、Shenandoah等先进的垃圾收集器,ZGC在实现细节上做了一些不同的权衡选择。譬如G1需要通过写屏障来维护记忆集,才能处理跨代指针,得以实现Region的增量回收。记忆集要占用大量的内存空间,写屏障也对正常程序运行造成额外负担,这些都是权衡选择的代价。
2024-01-09 14:35:39
1363
原创 Redis遇到过的问题 (Could not get a resource from the pool )
其中查看所有连接的展示的列表内容我在下方标出,注意看下idle这个字段,代表的空闲时间,单位是秒,这时可以看到idle的时间非常长,所以我这边确定程序获取获取大量的redis连接资源并且没有释放。否则,断开与 Redis 的连接。需要注意的是redisTemplate使用的是自动管理连接池,按道理来说调用完之后会自动释放连接,但是当redis开启了事务的时候,就需要手动释放连接,所以解决方案有两种。这么常用的方法,基于习惯,Java 在 jdk1.7 之后为我们提供了一个很好的方法。
2023-12-25 19:54:04
2194
原创 common-pool的GenericObjectPool源码创建borrowObject方法研读
对象池主要管理对象的池,包含借用,归还,添加对象,校验对象是否有效等管理功能。
2023-12-21 11:05:48
549
原创 jedisCluster模式下使用scan命令来删除指定前缀的字符串
之前搜了网上很多文章,发现jedisCluster.getClusterNodes()在jedis的4.x版本获取的对象Map,而不是Map。针对这个情况进行代码改造。因业务需要,需要对指定redis的前缀批量删除,如果直接使用keys 命令在数据量比较大的情况下会导致redis集群崩溃或者业务hang住。利用scan通过分页方式来拿到指定的key前缀,在进行相关数据的删除。来获取jedisNode客户段,具体代码如下。
2023-12-20 18:42:58
1361
原创 redission源码解读
总的来说,如果只是简单的使用Redis进行一些基本操作,可以选择使用Jedis;如果需要使用到Redis的高级功能或者需要进行分布式开发,建议选择Redisson。而Redisson提供了更加丰富的API,包括分布式锁、集合、队列等高级功能。线程模型不同:Jedis是单线程模型,而Redisson是异步线程模型。支持集群模式不同:Jedis只支持基本的单机模式和主从模式,而Redisson支持Redis集群模式。可扩展性不同:Redisson具有更好的可扩展性,可以通过自定义配置实现更多的功能。
2023-11-20 16:24:49
172
原创 mysql隐式转换转换引起的bug
2、若字符串是以数字开头,且全部都是数字,则转换为数字结果是整个字符串;部分是数字,则转换为数字结果是截止到第一个不是数字的字符为止。理解: varchar str = "123dafa",转换为数字是123。3、若字符串不是以数字开头,则转换为数字结果是 0。本案例正好符合第三种情况,因为subject_id是int类型,而过滤条件是varchar类型,同时首字母是英文而不是数字,导致默认转换为0,所以查询出来不一样的结果。生产环境中遇到一个情况情况 ,过滤数据发现过滤不掉相关值情况,具体情况如下。
2023-11-10 11:10:37
831
原创 线程池阻塞队列长度设置失误导致任务一直被阻塞未能执行
3、更加上述线程池执行逻辑,因为业务执行很长时间,而阻塞队列设置很大,则导致后续提交的任务都放到阻塞队列了,从而导致任务挤压。改进措施,根据任务执行时间合理设置LinkedBlockingQueue的大小,比如设置20个,最大线程数也设置大点。1、生产环境中有个接口耗时比较久,然后自己的阻塞队列没有设置默认值,导致后续提交过来的任务一直在阻塞队列中,具体代码如下。2、线程池的执行逻辑。
2023-10-27 11:27:52
320
原创 AQS中 state 和 waitStatus 分别是干什么的?
它是AQS的核心字段之一,用于控制线程的访问和操作。字段用于表示节点在等待队列中的状态,通过这两个字段,AQS可以实现线程的等待和唤醒机制。字段,如果需要等待,则线程会进入等待状态;字段的设置和检查,AQS可以控制线程的等待和唤醒。类中的一个字段,在AQS中用于构建等待队列和条件队列。字段的含义和用途是由具体的同步器实现决定的。字段的值,根据具体的实现逻辑进行相应的操作。字段用于表示节点在等待队列中的状态。是用于管理线程等待和唤醒的重要字段。字段用于表示共享资源的状态或计数,而。字段,并唤醒等待的线程。
2023-10-07 17:33:34
763
原创 锁,事务,多线程的关系
事务具备原子性、一致性、隔离性和持久性(ACID)的特性,用于确保数据库的完整性和一致性。在并发环境下,多个线程或进程可以同时进行数据库操作,而事务机制可以保证这些操作按照一定的顺序执行,避免数据异常和冲突。通过合理地使用锁和事务机制,可以确保多线程环境下的数据一致性和操作正确性。在实际应用中,锁通常被用于控制对共享资源的访问,避免多个线程同时修改数据而导致的数据不一致问题。锁、事务和多线程之间有密切的关系,它们都是在并发编程中用于保证数据一致性和操作正确性的重要概念。
2023-09-22 16:19:22
598
原创 基于springboot线程池,来提高接口并发相关demo的性能压测和思考
【代码】基于springboot线程池,来提高接口并发相关demo的性能压测和思考。
2023-09-15 15:37:55
472
原创 基于springboot实现多线程抢锁的demo
使用 jstack 88023 |grep SimpleAsyncTaskExecutor-62 命令可以查看相关线程是否存在。本代码基于定时调度和异步执行,如果只加异步处理,会导致当前任务未执行完,下个任务到点也不会触发执行。
2023-09-04 19:00:35
727
原创 springboot异步多线程的实现
4、如果启用异步线程池,需要在启动类加上 @EnableAsync(proxyTargetClass = true) 注解。3、controller层服务调用。1、配置线程池相关参数。
2023-08-03 15:33:39
552
原创 Springboot项目报错解决方案
问题应该在本身的代码上,但是,我记得代码是测试过的,没有问题。但是,没有其他办法,只能顺着提示一步步寻找问题所在。最终,确实问题出在代码上。在排除问题时,一直没有发现什么异常,后续通过堆栈错误,看到最后的错误信息。3、每次修改过代码以后,都要记得进行测试,确保修改是正确的。4、迁移其他项目的Service服务时,看看调用的任务关系图。1、解决问题,不要急躁,要淡定,淡定,淡定。2、仔细看报错信息。
2023-05-19 19:33:28
556
kafka-manager-2.0.0.1_prod.tgz
2019-09-18
《深入理解Java虚拟机:JVM高级特性与最佳实践》第二版和源码
2019-04-01
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人