JVM-性能优化工具 MAT
一、MAT下载和安装
1、概述
MAT(Memory Analyzer Tool
)工具是一款功能强大的]ava
堆内存分析器。可以用于查找内存泄漏以及查看内存消耗情况。MAT是基于Eclipse
开发的,不仅可以单独使用,还可以作为插件的形式嵌入在Eclipse
中使用。是一款免费的性能分析工具,使用起来非常方便。
2、下载地址:
https://www.eclipse.org/mat/downloads.php
我目前电脑的JDK安装环境是1.8的,所以需要下载对应JDK1.8版本的MAT版本
3、安装
下载后解压,点击MemoryAnalyzer.exe进行启动
4、安装出现的报错问题
4.1、MAT版本和JDK版本不一致
问题描述:
要是直接下载最新版的MAT,可能需要高版本JDK才行。启动是需要JDK11或者更高的版本,我本地JDK版本是1.8,所以会报JDK版本不适合。
解决方法:
在MemoryAnalyzer.ini 中加入指定jdk的地址, (jdk不用安装直接下载 解压指定bin/javaw.exe就可)
-vm
D:/java/jdk1.8.0_211/binbin/javaw.exe
-vm
D:/java/jdk1.8.0_211/binbin/javaw.exe
-startup
plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.700.v20180518-1200
-vmargs
-Xmx1024m
4.2、堆dump文件较大、使用MAT打开的时候总是抛出 Java Heap Error
问题描述:
有时候线上产生的堆dump文件较大,如果你的hprof文件没有问题的话,使用MAT打开的时候总是抛出 Java Heap Error. 可能是默认的1024m内存不够用了。
解决办法:
找到MAT的安装目录,找到MemoryAnalyzer.ini 修改其中的-Xmx即可
将-Xmx1024m 调大即可
5、jmap命令拿到dump日志文件
jmap是Java虚拟机自带的一个命令行工具,可以用来生成JVM内存快照(Heap dump)文件。以下是使用jmap命令生成dump文件的步骤:
jmap -dump:format=b,file=heap.bin <pid>
通常情况下,在生产环境中使用jmap命令生成Heap dump文件时,建议把生成的文件下载到本地进行分析,以减少对生产环境的干扰。另外,在生成Heap dump文件时,一定要确保Java应用程序正常运行,否则可能会导致生成的文件不完整或者无法正确解析。
二、MAT工具排查分析OOM
1、故障现象:
集群应用服务器在高并发请求的情况下会不定时地因为响应超时而报警,但是很快又超时解除,恢复正常,如此反复,让运维人员非常苦恼。
原因分析: 来到一家新公司,一个重构项目的开发人员估计搞不动了,最后选择跑路,我的到来正好接盘了这个有好多bug的项目。配合测试功能测试完结束后,进行压测。发现查询接口只要并发一起来就会出现错乱的现象。先是排查原先写的代码是否有问题,没发现问题,然后我以为是脏读,调整的事务的隔离级别等等方法,发现还是解决不了。最后没办法在方法上加了一个synchronized锁,再进行压测时,虽然吞吐量不高,但是不会有报错的现象。等开始正式切换系统进行上线时。因为每天会有至少20w的查询量。只要某个时间段只要请求量很高就会出现连接超时的现象。当时也想到是因为加了synchronized造成高并发请求下,很多请求一直在等待,最后因为时间太久而造成的超时。所以我就下载了dump文件,使用MAT工具进行分析。果然是这个锁造成的。这是的我已经对代码稍微熟悉了,分析什么造成的错乱现象。发现代码有一处用到了共享变量,造成每次高并发去请求出现的错乱现象。我当时心里。。。
参考https://blog.csdn.net/cl939974883/article/details/124581664 文档,确实是synchronized造成的
下面详说一下MAT如何分析dump文件
2、MAT
分析 OOM
问题通常思路:
- 通过支配树功能或直方图功能查看消耗内存最大的类型,来分析内存泄露的大概原因;
- 查看那些消耗内存最大的类型、详细的对象明细列表,以及它们的引用链,来定位内存泄露的具体点;
- 配合查看对象属性的功能,可以脱离源码看到对象的各种属性的值和依赖关系,帮助我们理清程序逻辑和参数;
- 辅助使用查看线程栈来看 OOM 问题是否和过多线程有关,甚至可以在线程栈看到 OOM 最后一刻出现异常的线程。
3、使用MAT定位问题:
-
定位问题方式一:
现在有一个
OOM
后得到的堆转储文件 java_pid29569.hprof,现在要使用 MAT 的直方图
、支配树
、线程栈
、OQL
等功能来分析此次 OOM 的原因。首先,用 MAT 打开后先进入的是概览信息界面,可以看到整个堆是 437.6MB:
那么,这 437.6MB 都是什么对象呢?如图所示,工具栏的第二个按钮可以打开直方图,直方图按照类型进行分组,列出了每个类有多少个实例,以及占用的内存。可以看到,char[]字节数组占用内存最多,对象数量也很多,结合第二位的 java.lang.String 类型对象数量也很多,大概可以猜出(String 使用 char[]作为实际数据存储)程序可能是被字符串占满了内存,导致 OOM。
在char[]
上点击右键,选择List objects->with incoming references
,就可以列出所有的char[]
实例,以及每个char[]
的整个引用关系链:
随机展开一个 char[],如下图所示:
接下来,我们按照红色框中的引用链来查看,尝试找到这些大char[]
的来源: -
在①处看到,这些
char[]
几乎都是 10000 个字符、占用 20000 字节左右(char 是 UTF-16,每一个字符占用 2 字节); -
在②处看到,char[]被
String
的value
字段引用,说明 char[]来自字符串; -
在③处看到,
String
被ArrayList
的elementData
字段引用,说明这些字符串加入了一个ArrayList
中; -
在④处看到,
ArrayList
又被FooService
的data
字段引用,这个ArrayList
整个RetainedHeap
列的值是 431MB。 -
左侧的蓝色框可以查看每一个实例的内部属性,图中显示
FooService
有一个data
属性,类型是ArrayList
。Retained Heap(深堆)
:代表对象本身和对象关联的对象占用的内存;Shallow Heap(浅堆)
:代表对象本身占用的内存。
比如,我们的 FooService 中的 data 这个 ArrayList 对象本身只有 16 字节,但是其所有关联的对象占用了 431MB 内存。这些就可以说明,肯定有哪里在不断向这个 List 中添加 String 数据,导致了 OOM。如果我们希望看到字符串完整内容的话,可以右键选择 Copy->Value,把值复制到剪贴板或保存到文件中:
这里,我们复制出的是 10000 个字符 a(下图红色部分可以看到)。
看到这些,我们已经基本可以还原出真实的代码是怎样的了,定位到了问题代码。 -
定位问题方式二:
其实,我们之前使用直方图定位FooService
,已经走了些弯路。你可以点击工具栏中第三个按钮(下图左上角的红框所示)进入支配树界面。这个界面会按照对象的Retained Heap
倒序直接列出占用内存最大的对象。
可以看到,第一位就是FooService
,整个路径是FooSerice->ArrayList->Object[]->String->char[]
(蓝色框部分),一共有 21523 个字符串(绿色方框部分)。通常使用这种方式可以一步到位的定位出问题所在。 -
借助MAT寻到具体问题原因
我们就从内存角度定位到FooService
是根源了。那么,OOM
的时候,FooService
是在执行什么逻辑呢?为解决这个问题,我们可以点击工具栏的第五个按钮(下图红色框所示)。打开线程视图,首先看到的就是一个名为 main 的线程(Name 列),展开后果然发现了
FooService
:
先执行的方法先入栈,所以线程栈最上面是线程当前执行的方法,逐一往下看能看到整个调用路径。 -
因为我们希望了解
FooService.oom()
方法,看看是谁在调用它,它的内部又调用了谁,所以选择以FooService.oom()
方法(蓝色框)为起点来分析这个调用栈。 -
往下看整个绿色框部分,
oom()
方法被OOMApplication
的run
方法调用,而这个run
方法又被SpringAppliction.callRunner
方法调用。 -
看到参数中的
CommandLineRunner
你应该能想到,OOMApplication
其实是实现了CommandLineRunner
接口,所以是SpringBoot
应用程序启动后执行的。 -
以
FooService
为起点往上看,从紫色框中的Collectors
和IntPipeline
,大概也可以猜出,这些字符串是由Stream
操作产生的。 -
再往上看,可以发现在
StringBuilder
的append
操作的时候,出现了OutOfMemoryError
异常(黑色框部分),说明这这个线程抛出了OOM
异常。我们看到,整个程序是
Spring Boot
应用程序,那么FooService
是不是Spring
的Bean
呢,又是不是单例呢?如果能分析出这点的话,就更能确认是因为反复调用同一个
FooService
的oom
方法,然后导致其内部的ArrayList
不断膨胀。点击工具栏的第四个按钮(如下图红框所示),来到
OQL
界面。在这个界面,我们可以使用类似SQL
的语法,在dump
中搜索数据(你可以直接在MAT
帮助菜单搜索OQL Syntax
,来查看OQL
的详细语法)。
比如,输入如下语句搜索 FooService 的实例:SELECT * FROM org.geekbang.time.commonmistakes.troubleshootingtools.oom.FooService
可以看到只有一个实例,然后我们通过 List objects 功能搜索引用 FooService 的对象:
可以看到,一共两处引用: -
第一处是,
OOMApplication
使用了FooService
。 -
第二处是一个
ConcurrentHashMap
。可以看到,这个HashMap
是DefaultListableBeanFactory
的singletonObjects
字段,可以证实FooService
是Spring
容器管理的单例的Bean
。
4、结论
到现在为止,虽然没看程序代码,但是已经大概知道程序出现 OOM 的原因和大概的调用栈了。再贴出程序来对比一下,果然和我们看到得一模一样:
@SpringBootApplication
public class OOMApplication implements CommandLineRunner {@AutowiredFooService fooService;public static void main(String[] args) {SpringApplication.run(OOMApplication.class, args);}@Overridepublic void run(String... args) throws Exception {//程序启动后,不断调用Fooservice.oom()方法while (true) {fooService.oom();}}
}
@Component
public class FooService {List<String> data = new ArrayList<>();public void oom() {//往同一个ArrayList中不断加入大小为10KB的字符串data.add(IntStream.rangeClosed(1, 10_000).mapToObj(__ -> "a").collect(Collectors.joining("")));}
}
到这里,我们使用 MAT 工具从对象清单、大对象、线程栈等视角,分析了一个 OOM 程序的堆转储。可以发现,有了堆转储,几乎相当于拿到了应用程序的源码 + 当时那一刻的快照,OOM 的问题无从遁形。
三、jvm-jps、jinfo、jstat、jstack、jmap 基本使用
给系统定位问题的时候,知识经验是基础,应用数据是依据,工具是手段,在jvm中,我们常见的数据包括: 运行日志、堆栈信息、GC信息、线程快照(threaddump/javacode)、堆快照(heapdump/hporf),jdk提供给我们了很实用的工具来分析,定位解决这些问题,这些工具包含于jdk中,并且以java实现,方便在不同的环境中不用安装其他依赖库即可使用,很是方便。下面分别介绍 jps、jinfo、jstat、jstack、jmap
,本文使用的jdk版本为1.8.0_11
1、jps ( jvm process status tool ) 虚拟机进程工具
配置项 | 作用 |
---|---|
-q | 忽略主类的名称,只输出pid |
-m | 输出启动类main函数的参数 |
-l | 输出主类名,如果进程执行的为jar,则输出jar路径 |
-v | 输出具体进程启动时jvm参数 |
1.命名格式
jps [options] pid
2.常用方式
- jps -lv : 输出启动类名与启动时jvm参数,可以方便的看到各个tomcat的自定义参数配置
- jps -lv |grep project_name : 在上述基础上过滤出自己想要查看的项目的信息
2、jinfo ( configuration info for java ) 显示虚拟机配置信息
1.常用用法
- jinfo pid : 显示jvm系统属性与vm参数信息
- jinfo -flags pid : 显示jvm vm参数信息,如最大最小堆,默认堆,垃圾收集器参数等
- jinfo -sysprops pid : 显示jvm系统属性
- jinfo -flag : 显示特定vm参数值,例如 jinfo -flag MaxHeapSize pid 输出pid的最大堆内存
3、jstat ( jvm statistics monitoring tool) 收集虚拟机各方面运行数据
1、语法格式
jstat [ option pid [interval[s|ms] [count]]]
说明: interval 表示循环时间间隔,默认单位为ms,可以在直接使用s/ms指定单位,如 60ms/1s, count 表示输出几次 例:
jstat gc pid 1s 20
每1s查询一次gc情况,查询20次
2、option 详解(主要分三类:类装载、垃圾收集、运行期编译状况)
配置项 | 作用 |
---|---|
-class | 监视类装载、卸载数量、总空间以及类装载所耗费的时间 |
-gc | 监视Java堆,包括Eden区、两survivor区、老年代、永久代等的容量、已用空间、GC时间合计等 |
-gccapacity | 与-gc基本相同,但关注点为Java堆各个区域使用到的最大、最小空间 |
-gcutil | 与-gc基本相同,但关注点为Java堆各个区域已使用空间占总空间的百分比 |
-gccause | 与-gcutil功能相同,但会额外输出导致上一次GC产生的原因 |
-gcnew | 监控新生代GC情况 |
-gcnewcapacity | 与-gcnew基本相同,但关注最大,最小空间 |
-gold | 监控老年代GC情况 |
-goldcapacity | 与-gcold基本相同,但关注最大,最小空间 |
-compiler | 输出被JIT编译过的方法、耗时等信息 |
-printcomplilation | 输出已经被JIT编译的方法 |
3、查看类装载卸载情况 jstat -class pid
属性 | 释义 |
---|---|
Loaded | 装载总数量 |
Bytes | 装载总大小 |
Unloaded | 卸载类的数量 |
Time | 加载和卸载类总共的耗时 |
4、查看GC情况 jstat -gc pid
属性 | 释义 |
---|---|
S0C | 新生代survivor0容量 |
S1C | 新生代survivor1容量 |
S0U | 新生代survivor0已使用大小 |
S1U | 新生代survivor1已使用大小 |
EC | 新生代eden区容量 |
EU | 新生代eden区已使用大小 |
OC | 老年代容量 |
OU | 老年代已使用大小 |
MC | 元数据容量,即方法区容量 |
MU | 元数据已使用空间 |
CCSC | 压缩类空间大小 |
CCSU | 压缩类空间使用大小 |
YGC | 新生代gc次数(young gc) |
YGCT | 新生代gc时间(s) |
FGC | 老生代gc次数(full gc) |
GCT | 总的gc时间,包括young gc和full gc |
5、查看GC情况,以百分比显示
jstat -gcutil pid
6、查看新生代GC情况
jstat -gcnew pid
属性 | 释义 |
---|---|
S0C | 新生代survivor0容量 |
S1C | 新生代survivor1容量 |
S0U | 新生代survivor0已使用大小 |
S1U | 新生代survivor1已使用大小 |
TT | 对象在新生代存活的次数 |
MTT | 对象在新生代存活的最大次数 |
DSS | 期望的幸存区大小 |
EC | eden区大小 |
EU | eden区已使用大小 |
YGC | young gc次数 |
YGCT | young gc 时间 (秒) |
7、查看老年代GC情况
jstat -gcold pid
8、查看各空间容量
jstat -gccapacity pid
属性 | 释义 |
---|---|
NGCMN | 新生代最小容量 |
NGCMX | 新生代最大容量 |
NGC | 当前新生代容量 |
S0C | survivor0大小 |
S1C | survivor0大小 |
EC | EDEN区大小 |
OGCMN | 老年代最小容量 |
OGCMX | 老年代最大容量 |
OGC | 当前老年代大小 |
MCMN | 元数据最小容量 |
MCMX | 元数据最大容量 |
CCSMN | 最小压缩类空间大小 |
CCSMX | 最大压缩类空间大小 |
CCSC | 当前压缩类空间大小) |
9、查看编译情况
jstat -compiler pid
4、jmap ( memory map for java ) 虚拟机堆快照工具
1、常用用法
- jmap -heap pid 查看当前jvm heapdump与垃圾收集器的使用情况
- jmap -dump:format=b,file=/temp/filename.hprof pid 转储堆快照,生成hprof文件到指定路径
- jmap -histo pid 列出当前heap中对象状况,附字节码与java对象映射表
5、jstack ( stack trace for java ) 虚拟机线程快照工具
效果演示: 会显示所有线程的各种信息,可以用来排查死锁,或线程长时间停滞的问题…
相关文章:

JVM-性能优化工具 MAT
一、MAT下载和安装 1、概述 MAT(Memory Analyzer Tool)工具是一款功能强大的]ava堆内存分析器。可以用于查找内存泄漏以及查看内存消耗情况。MAT是基于Eclipse开发的,不仅可以单独使用,还可以作为插件的形式嵌入在Eclipse中使用…...
Python Flask flasgger api文档[python/flask/flasgger]
首先需要安装依赖: pip install flasgger封装swagger.py文件,代码如下: from flasgger import Swagger swagger Swagger() 然后在主应用中(项目入口文件)加入以下代码: from flask import Flask from …...

k8s常见命令
基础知识 1,deployment和pod关系 一个pod里面好几个container,deployment是针对这个pod的配置文件,比如设置这个pod有几个副本 2,ip地址 node有ip,pod也有ip。 node的ip用于集群内部和外部访问,pod用于…...

Unity3d C#实现调取网络时间限制程序的体验时长的功能
前言 如题的需求应该经常在开发被提到,例如给客户体验3–5天的程序,到期后使其不可使用,或者几年的使用期限。这个功能常常需要使用到usb加密狗来限制,当然这也的话就需要一定的硬件投入。很多临时提供的版本基本是要求软件来实现…...

常静相伴:深度解析C++中的const与static关键字
个人主页:北海 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏✨收录专栏:C/C🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!ǹ…...

Linux入门之进程信号|信号产生的方式
文章目录 一、信号入门 1.linux信号的基本概念 2.使用kill -l 命令可以查看系统定义的信号列表 3.信号处理常见方式 二、产生信号 1.通过终端按键产生信号 2.通过调用系统函数向进程发信号 3.由软条件产生信号 4.硬件异常产生信号 1. /0异常 2.模拟野指针 一、信号入门…...

Unity中的数学基础——贝塞尔曲线
一:前言 一条贝塞尔曲线是由一组定义的控制点P0到 Pn,n1为线性,n2为二次......第一个和最后一个控制点称为起点和终点,中间的控制点一般不会位于曲线上 获取两个点之间的点就是通过线性插值( Mathf.Lerp)…...

大数据平台安全主要是指什么安全?如何保障?
大数据时代已经来临,各种数据充斥着我们的生活与工作。随着数据的多样性以及复杂性以及大量性,大数据平台诞生了。但对于大数据平台大家都不是很了解,有人问大数据平台安全主要是指什么安全?如何保障? 大数据平台安全…...

Flutter的未来与趋势,23年还学吗?
随着移动应用市场的不断扩大,跨平台开发框架的需求也越来越大。Flutter框架可以帮助开发者在不同平台上快速开发高质量的移动应用程序,这种趋势将进一步推动Flutter的发展和普及。 作为一名前端开发工程师,学习Flutter框架是非常有必要的。因…...

RHCE——十三、Shell自动化运维编程基础
Shell 一、为什么学习和使用Shell编程二、Shell是什么1、shell起源2、查看当前系统支持的shell3、查看当前系统默认shell4、Shell 概念 三、Shell 程序设计语言1、Shell 也是一种脚本语言2、用途 四、如何学好shell1、熟练掌握shell编程基础知识2、建议 五、Shell脚本的基本元素…...

深入理解AMBA总线协议(AXI总结篇)
AXI总线已经是AMBA总线中最常见,使用最频繁的总线,并且没有之一。 可以说AXI总线已经成为了片上总线中最重要的协议,本篇文章打算花一些篇幅,帮大家总结一下AXI总线的学习重点、学习难点,以帮助大家更好更快的掌握AXI…...
建立无需build的react单页面应用SPA框架(2)
react-18.1.0,rc-easyui-1.2.9,babel-7.17.11 SPA还要处理的问题: (一)tabs切换事件通知 tabs切换时,自己的框架需要处理组件的生命周期,要有active/deactive,让组件能知道何时创…...

C# char曲线控件
一、char曲线显示随机数数据 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using Syst…...

远程访问本地jupyter notebook服务 - 无公网IP端口映射
文章目录 前言1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 前言 Jupyter Notebook,它是一个交互式的数据科学和计算环境,支持多种编程语言,如…...
flume系列之:记录一次消费大量Debezium数据,数据包含dml语句比较大,造成数据堆积在channel的解决方法
flume系列之:记录一次消费大量Debezium数据,数据包含dml语句比较大,造成数据堆积在channel的解决方法 一、背景二、相关技术博客三、flume层面解决方法四、debezium数据采集层面解决方法一、背景 Debezium采集了大量的数据,数据包含DMl语句,数据本身比较大。flume消费了大…...
Could not find artifact com.pageOffice:pageOffice:pom:4.3.0.2 in aliyunmaven
Could not find artifact com.pageOffice:pageOffice:pom:4.3.0.2 in aliyunmaven (https://maven.aliyun.com/repository/public) 仓库服务 阿里云云效 Maven 是什么 阿里云Maven中央仓库为 阿里云云效 提供的公共代理仓库,帮助研发人员提高研发生产效率&#x…...

2023年9月数据治理/项目管理/产品管理/商务礼仪企业内训定制
在节奏飞驰、风起云涌的企业世界中,为了企业的蓬勃发展,可以在内部或者外部挑选有经验的老师进行培训和学习。简而言之,任何一个企业想要发展,都少不了进行内训。 企业内训的好处 提高员工的技能和知识水平 通过不断地学习和培训…...
后端面试话术集锦第 九 篇:Activiti工作流面试话术
这是后端面试集锦第九篇博文——Activiti工作流面试话术❗❗❗ 1. 工作流话术 工作流这块儿,实际在工作中使用的时候,Activiti用的居多,当然还有一些其他的工作流引擎。 在网上看了也大概看了一下,其他的像JBPM以及workflow等用的情况来讲不是很多。 所以说Activiti目前…...

JS中方法、函数、属性是一个东西吗
在 JavaScript 中,方法、函数和属性是相关但不完全相同的概念。 方法(Method):在对象中,方法是对象的属性,但它的值是一个函数。方法可以通过对象来调用,并且可以访问对象的属性和其他方法。 …...

面经:微服务
文章目录 参考资料一. 微服务概述1. CAP理论2. BASE理论3. SpringBoot 与 SpringCloud对比 二. 服务注册:Zookeeper,Eureka,Nacos,Consul1. Nacos两种健康检查方式?2. nacos中负责负载均衡底层是如何实现的3. Nacos原理4. 临时实例和持久化(非临时)实例 …...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...