java进程引发的内存泄露问题排查分析

news2025/1/20 17:06:03

近期工作过程中遇到了一次容器内存不断增高,最终达到90%引发告警的情况。
特征1,把监控面板时间轴拉长会发现,重启后内存占用78%左右,每天增长1%,大约2周后会涨到90%触发告警(即如果2周内有代码发布部署,则需要以最新部署时间开始再往后推2周才会再次触发告警)。
特征2,生产环境14台机器,只有2台机器内存占用达到90%告警,这2台机器是内灰机器平常没有流量。

缉拿罪魁祸首进程

第一步自然是缉拿罪魁祸首了,登录服务器发现java进程RSS不断增高,一开始觉得很简单,以为是堆内存泄露,结果发现并没有想象中那么简单
#如何可以看出java进程占用RSS不断增长的呢?
执行 ps aux 即可看出各个进程的RSS使用情况,如下实际案例来看,PID是2669的进程RSS占用了5579008KB ,间隔一段时间再执行就可以看出来,一直在小范围增长


$ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

……
admin      2669 73.3 66.5 9308832 5579008 ?     Sl   15:13  15:52 /opt/xxxxxx/java/bin/java -Dspring.profiles.active=ppe -Dstdout=false -DlimitTime=30 -Ddruid.load.spifilter.skip -Dhsf.consumer.ini
……

#RSS小知识
RSS是什么单词的缩写?Resident Set Size,它是进程分配的物理内存的大小,单位为KB
RSS增长也有可能是合理的,观察一段时间后如果发现进程RSS地增长,也有可能是合理的情况,可能是java进程在运行过程创建对象造成的,但是随着周期性的JVM GC垃圾收集工作,过一段时间后再观察还是会RSS还降下来的,比如令天观察总比昨天RSS在增长,明天比今天也在增长,那么就不是合理的。

锁定到进程PID:2669 内存泄露
进程PID:2669 是java应用,内存泄露可能是来自堆内存,也可能是非堆内存,还有可能是堆外内存

逐个排除内存泄露点

第二步采用逐个排除法,依次分析内存泄露的可能性

堆内存泄露?

堆内存泄露?公司层面已经有了JVM监控面板,时间拉长到1天后会发现堆内存使用是涨涨跌跌,最终稳定在一个相对固定值上,初步可以排除堆内存泄露引发的问题了
在这里插入图片描述

注:如果想详细查看堆内存中对象的分布情况可以使用如下命令
jcmd 2669 GC.class_histogram > dump.log

非堆内存泄露?

非堆内存泄露?非堆内存包括了Metaspace,CompressedClassSpace,CodeHeap
Java应用的执行,JVM自身也需要消耗一些内存的,通过开启Native Memory Tracking,我们就能知道JVM自身消耗了多少内存。

书归正传,通过修改JVM参数并重启Java进程开启NativeMemory Tracking:
-XX:NativeMemoryTracking=detail

进程重启后,可以通过NMT的一些子命令(summary/detail/baseline/diff)查看Native Memory的占用情况:


sudo -u <user>jcmd <pid> VM.native_memory
sudo -u <user>jcmd <pid> VM.native_memory detail


完整命令:
alioopid=`ps aux|grep java|grep alsc-growth-fission|awk -F ' ' '{print $2}'`
jcmd $alioopid VM.native_memory scale=MB
jcmd $alioopid  VM.metaspace


命令结果:
28040:

Native Memory Tracking:

Total: reserved=6804MB, committed=5448MB
-                 Java Heap (reserved=4096MB, committed=4096MB)
                            (mmap: reserved=4096MB, committed=4096MB)

-                     Class (reserved=630MB, committed=424MB)
                            (classes #71617)
                            (  instance classes #68709, array classes #2908)
                            (malloc=14MB #249010)
                            (mmap: reserved=616MB, committed=410MB)
                            (  Metadata:   )
                            (    reserved=360MB, committed=358MB)
                            (    used=350MB)
                            (    free=9MB)
                            (    waste=0MB =0.00%)
                            (  Class space:)
                            (    reserved=256MB, committed=52MB)
                            (    used=47MB)
                            (    free=5MB)
                            (    waste=0MB =0.00%)

-                    Thread (reserved=1185MB, committed=125MB)
                            (thread #1176)
                            (stack: reserved=1180MB, committed=119MB)
                            (malloc=4MB #7058)
                            (arena=1MB #2351)

-                      Code (reserved=271MB, committed=181MB)
                            (malloc=13MB #53389)
                            (mmap: reserved=258MB, committed=168MB)

-                        GC (reserved=203MB, committed=203MB)
                            (malloc=18MB #88815)
                            (mmap: reserved=184MB, committed=184MB)

-                  Compiler (reserved=6MB, committed=6MB)
                            (malloc=6MB #5145)

-                  Internal (reserved=9MB, committed=9MB)
                            (malloc=9MB #17612)

-                     Other (reserved=262MB, committed=262MB)
                            (malloc=262MB #367)

-                    Symbol (reserved=58MB, committed=58MB)
                            (malloc=53MB #766877)
                            (arena=4MB #1)

-    Native Memory Tracking (reserved=20MB, committed=20MB)
                            (malloc=1MB #12232)
                            (tracking overhead=19MB)

-               Arena Chunk (reserved=57MB, committed=57MB)
                            (malloc=57MB)

-                    Module (reserved=6MB, committed=6MB)
                            (malloc=6MB #36247)

-              Synchronizer (reserved=1MB, committed=1MB)
                            (malloc=1MB #12399)


# 详细看一下metaspace空间的完整命令:
alioopid=`ps aux|grep java|grep alsc-growth-fission|awk -F ' ' '{print $2}'`
jcmd $alioopid  VM.metaspace


jcmd 28040  VM.metaspace
28040:

Total Usage - 8641 loaders, 71659 classes:
  Non-Class: 25515 chunks,   359.73 MB capacity,   351.59 MB ( 98%) used,     6.57 MB (  2%) free,    11.78 KB ( <1%) waste,     1.56 MB ( <1%) overhead, deallocated: 16419 blocks with 4.91 MB
      Class: 10152 chunks,    52.04 MB capacity,    47.46 MB ( 91%) used,     3.96 MB (  8%) free,   448 bytes ( <1%) waste,   634.50 KB (  1%) overhead, deallocated: 1413 blocks with 461.28 KB
       Both: 35667 chunks,   411.77 MB capacity,   399.06 MB ( 97%) used,    10.53 MB (  3%) free,    12.22 KB ( <1%) waste,     2.18 MB ( <1%) overhead, deallocated: 17832 blocks with 5.36 MB


Virtual space:
  Non-class space:      360.00 MB reserved,     359.75 MB (>99%) committed
      Class space:      256.00 MB reserved,      52.12 MB ( 20%) committed
             Both:      616.00 MB reserved,     411.88 MB ( 67%) committed



Chunk freelists:
   Non-Class:

 specialized chunks:    1, capacity 1.00 KB
       small chunks: (none)
      medium chunks: (none)
   humongous chunks: (none)
              Total:    1, capacity=1.00 KB
       Class:

 specialized chunks:    1, capacity 1.00 KB
       small chunks:    9, capacity 18.00 KB
      medium chunks: (none)
   humongous chunks: (none)
              Total:   10, capacity=19.00 KB

Waste (percentages refer to total committed size 411.88 MB):
              Committed unused:     88.00 KB ( <1%)
        Waste in chunks in use:     12.22 KB ( <1%)
         Free in chunks in use:     10.53 MB (  3%)
     Overhead in chunks in use:      2.18 MB ( <1%)
                In free chunks:     20.00 KB ( <1%)
Deallocated from chunks in use:      5.36 MB (  1%) (17832 blocks)
                       -total-:     18.18 MB (  4%)


MaxMetaspaceSize: 768.00 MB
CompressedClassSpaceSize: 256.00 MB
Initial GC threshold: 768.00 MB
Current GC threshold: 768.00 MB
CDS: off

InitialBootClassLoaderMetaspaceSize: 4.00 MB

# 详细看一下CodeHeap空间的完整命令:

$jcmd 28040 Compiler.codecache
28040:
CodeHeap 'non-profiled nmethods': size=126784Kb used=80270Kb max_used=80270Kb free=46513Kb
 bounds [0x00007f50f2143000, 0x00007f50f6fb3000, 0x00007f50f9d13000]
CodeHeap 'profiled nmethods': size=126780Kb used=93363Kb max_used=94520Kb free=33417Kb
 bounds [0x00007f50ea574000, 0x00007f50f0214000, 0x00007f50f2143000]
CodeHeap 'non-nmethods': size=8580Kb used=2808Kb max_used=5690Kb free=5772Kb
 bounds [0x00007f50e9d13000, 0x00007f50ea2b3000, 0x00007f50ea574000]
 total_blobs=56234 nmethods=54803 adapters=1336
 compilation: enabled
              stopped_count=0, restarted_count=0
 full_count=0

结论:没有关系,发现’non-profiled nmethods’,‘profiled nmethods’,‘non-nmethods’ 三个部分size之和才256M,不会造成整个容器内存膨胀到100%

至此发现非堆空间的使用量跟启动脚本的是一致的,并没有超过启动脚本指定的阀值,所以这部分也排除掉了。

附:启动脚本的几个核心参数:

SERVICE_OPTS="${SERVICE_OPTS} -Xms4g -Xmx4g"
SERVICE_OPTS="${SERVICE_OPTS} -XX:MetaspaceSize=768m -XX:MaxMetaspaceSize=768m -XX:CompressedClassSpaceSize=256m"
SERVICE_OPTS="${SERVICE_OPTS} -XX:MaxDirectMemorySize=512m"
SERVICE_OPTS="${SERVICE_OPTS} -XX:ReservedCodeCacheSize=256m -XX:+PrintCodeCache"

当然了,还可以把上述命令封装到一个脚本中写入到linux crontab中,让它自动周期执行

cat > /home/admin/$APP_NAME/logs/monitor.sh  <<EOF

echo -e "\n\n\n\n\n"
echo "=============="
echo "$(date "+%Y-%m-%d %H:%M:%S")"
echo "=============="

ps aux|grep java

alioopid=`ps aux|grep java|grep alsc-growth-fission|awk -F ' ' '{print $2}'`
jcmd $alioopid VM.native_memory scale=MB

EOF

chmod 777 /home/admin/$APP_NAME/logs/logs/monitor.sh 


* * * * * /bin/sh /home/admin/app_name_xxx/logs/monitor.sh 2>&1 >> /home/admin/app_name_xxx/logs/monitor.log

堆外内存泄露?

堆外内存泄露?那么接下来的怀疑对象就是堆外内存这部分了,然而这部分的监控显示这部分内存使用非常稳定,堆外内存一直只占用200m内存左右,也没有增长过,也被排除掉了。
在这里插入图片描述

JVM工具江郎才尽,希望寄托到Linux命令工具pmap

JVM工具江郎才尽,希望寄托到Linux命令工具pmap,关于JVM内存泄露分析工具能想到的都用到了,在还没有头绪的情况下,接下来只能靠pmap命令来进一步分析了,首先去看一下ARENA区,在高并发的应用中,往往ARENA区占用的内存会比较多。为什么先看ARENA区的内存占用呢?是因为这个步骤是不需要重启JVM进程就可以完成的。


alioopid=`ps aux|grep java|grep $APP_NAME|awk -F ' ' '{print $2}'`
pmap $alioopid -x | sort -k 2 -n -r |less



# 如果存在大量大小为65536或60000左右的内存区域,则很大

ps可能是ARENA区域占用了太多的内存,如图2所示:

Address           Kbytes     RSS   Dirty Mode  Mapping
0000000700000000 4246912 4225732 4225732 rw---   [ anon ]
0000000803360000  463488       0       0 -----   [ anon ]
00007f252b556000  141992       0       0 r--s- modules
00007f250c000000  131072   77024   77024 rw---   [ anon ]
00007f2338000000  131072   82792   82792 rw---   [ anon ]
00007f252381d000  104192  104192  104192 rwx--   [ anon ]
00007f24e5abe000  103688     448       0 r---- locale-archive
00007f251bae5000   97728   97692   97692 rwx--   [ anon ]
00007f2534000000   65536   39080   39080 rw---   [ anon ]
00007f24f4000000   65536   65536   65536 rw---   [ anon ]
00007f24e0000000   65536   65520   65520 rw---   [ anon ]
00007f245c000000   65516   25140   25140 rw---   [ anon ]
00007f2430000000   65508   55648   55648 rw---   [ anon ]
00007f2500021000   65404       0       0 -----   [ anon ]
00007f24f0021000   65404       0       0 -----   [ anon ]
00007f24c8021000   65404       0       0 -----   [ anon ]
00007f2454021000   65404       0       0 -----   [ anon ]
00007f2424021000   65404       0       0 -----   [ anon ]
00007f241c021000   65404       0       0 -----   [ anon ]
00007f2418021000   65404       0       0 -----   [ anon ]
00007f2414021000   65404       0       0 -----   [ anon ]
00007f240c021000   65404       0       0 -----   [ anon ]
00007f2404021000   65404       0       0 -----   [ anon ]
00007f23f4021000   65404       0       0 -----   [ anon ]
00007f23ec021000   65404       0       0 -----   [ anon ]
00007f23e8021000   65404       0       0 -----   [ anon ]
00007f239c021000   65404       0       0 -----   [ anon ]
00007f2368021000   65404       0       0 -----   [ anon ]
00007f2358021000   65404       0       0 -----   [ anon ]
00007f22c8021000   65404       0       0 -----   [ anon ]
00007f22bc021000   65404       0       0 -----   [ anon ]
00007f2270021000   65404       0       0 -----   [ anon ]
00007f2254021000   65404       0       0 -----   [ anon ]
00007f21e0021000   65404       0       0 -----   [ anon ]
00007f21a4021000   65404       0       0 -----   [ anon ]
00007f2184021000   65404       0       0 -----   [ anon ]
00007f2124021000   65404       0       0 -----   [ anon ]
00007f2100021000   65404       0       0 -----   [ anon ]
00007f2058021000   65404       0       0 -----   [ anon ]
00007f2014021000   65404       0       0 -----   [ anon ]

注:pmap命令的输出结果几个部分详细含义:

Address           Kbytes     RSS   Dirty  Mode  Mapping

Address:内存映射的起始地址。
Kbytes:内存映射的大小,以KB为单位。
RSS(KB):驻留内存大小,即实际使用的内存。
Dirty(KB):脏页大小,即被修改过的内存页。
Mode:内存映射的访问权限(r:可读,w:可写,x:可执行)。
Mapping:内存映射的来源(文件、设备、匿名内存等)。

可以看到64M内存块非常多,间隔一天后会发现64M内存块数量还会增多,这个跟每天的内存增长情况是可以对上的,那么问题来了,64M内存块存放的内容是什么,为什么每天都会增加呢?
glibc 使用内存池为 java 应用通过 malloc 申请堆外内存,当 jvm 回收内存归还操作系统时,操作系统在 free 的时候并不会真正释放内存,而是维护到 glibc 的内存池中供下次使用,从而避免重复申请(当时也有个想法 jvm 和 linux 层面的内存监控不一致,是不是 linux 并未真正释放内存)

$ldd /opt/xxxxxx/java/bin/java
  linux-vdso.so.1 =>  (0x00007ffdd29e6000)
  /lib/libsysconf-alibaba.so (0x00007f9037e4a000)
  libjemalloc.so.2 => /opt/xxxxxx/java/bin/../lib/libjemalloc.so.2 (0x00007f9037c01000)
  libz.so.1 => /lib64/libz.so.1 (0x00007f90379e7000)
  libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f90377cb000)
  libjli.so => /opt/xxxxxx/java/bin/../lib/jli/libjli.so (0x00007f90375b9000)
  libdl.so.2 => /lib64/libdl.so.2 (0x00007f90373b5000)
  libc.so.6 => /lib64/libc.so.6 (0x00007f9036fe7000)
  librt.so.1 => /lib64/librt.so.1 (0x00007f9036dde000)
  libm.so.6 => /lib64/libm.so.6 (0x00007f9036adc000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f9038251000)
根据第4行内容,可以看到上面使用的是jemalloc(不是原生的 glibc 版本,这是因为我使用的是AJDK,AJDK底层已经采用了性能更好的jemalloc替换工具),为了验证是否能自动释放内存碎片,手动执行调用 malloc_trim 函数:
alioopid=`ps aux|grep java|grep $APP_NAME|awk -F ' ' '{print $2}'`
gdb --batch --pid=$alioopid   -ex "call (int)malloc_trim(0)"

……
[New LWP 7568]
[New LWP 7569]
[New LWP 7570]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
0x00007f2310b36017 in pthread_join () from /lib64/libpthread.so.0

Thread 339 "sentinel-system" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f226fded700 (LWP 3890)]
0x00007f22fd1ed557 in ?? ()
The program received a signal in another thread while
making a function call from GDB.
Evaluation of the expression containing the function
(malloc_trim) will be abandoned.
When the function is done executing, GDB will silently stop.
[Inferior 1 (process 2601) detached]

验证结果返回1表明有内存释放(0表示无内存释放),说明存在内存优化空间。执行完成之后再次查看此java进程内存占用,发现已经下降到3G多了(之前是6G)
在这里插入图片描述

方法1:禁用thread arena

这种情况下,最简单粗暴的办法是在JVM启动参数中增加配置:

export MALLOC_ARENA_MAX=1 

这种解决问题的思路是禁用thread arena,经过预发环境验证此思路可行(什么是thread arena?如果应用程序每次分配内存的时候都通过系统调用 mmap,sbrk等来分配,效率会很低,所以glibc 中实现了一个内存池,应用程序使用内存的时候通过glibc的内存池来提供,早期的 glibc 版本中,只有一个内存池,称为 main arena,在多线程场景中,每次分配和释放需要进行加锁。后来为了降低锁的粒度,从glibc 2.10版本开始引入了 thread arena,线程在申请内存的时候,glibc 为他创建一个 thread arena,这个内存池的大小一般是64M,thread arena被不被某个线程独占,全部的 thread arena被加入到环形链表,被所有线程共享使用。)

方法2:升级ajdk到最新reelase版本

那么为什么之前没有内存泄漏,最近为什么会发生呢,联想到JDK近期版本升级过(jdk8->jdk11), 进一步思考会不会新版本会不会有Bug呢,结果根据JDK发布记录还真找到了一个堆外内存泄漏的Bug

AJDK 11.0.14.13_fp1发布内容:
● G1: 修复一个G1BarrierSkipDCQ下堆外内存泄漏问题. Redirty使用的C数据结构只在Full GC时清空, 在Young GC时没有清空.
○ 这个也可以解释为什么有流量的机器内存反而没有一直上涨(有流量的机器随着运行肯定会不断创建对象,也一会会触发fullGC)

发现应用使用的jdk版本比这个版本号要小,那么解决这个问题就是升级到jdk11的最新版本,经过预发环境验证此思路可行
附修复此Bug的关键代码:
在这里插入图片描述

总结

上述2个方法都是可行的,方法1其实是禁用了thread arena,对性能是有一定影响的,故更加推荐方法2,也在此友情提醒大家升级JDK11时尽可能选择最新发布的release版本,避免重复踩坑

参考文章
https://dbaplus.cn/news-134-4002-1.html
https://easyice.cn/archives/341

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/469201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022-04-27:用go语言重写ffmpeg的remuxing.c示例。

2022-04-27&#xff1a;用go语言重写ffmpeg的remuxing.c示例。 答案2022-04-27&#xff1a; ffmpeg的remuxing.c是一个用于将多媒体文件从一种容器格式转换为另一种容器格式的命令行工具。它可以将音频、视频和字幕等元素从源文件中提取出来&#xff0c;并按照用户指定的方式…

构造函数和析构函数

1.构造函数 1.1 .构造函数概括 、构造函数是一个特殊的成员函数&#xff0c;名字与类名相同,创建类类型对象时由编译器自动调用&#xff0c;以保证每个数据成员都有 一个合适的初始值&#xff0c;并且在对象整个生命周期内只调用一次。 构造函数是特殊的成员函数&#xff0c…

简单认识 Postman界面操作

查看本文前 您需要先登录Postman 如果还没有处理好 可以先查看我的文章 Postman登录注册指导 右上角的 Home 代表主页 就是我们现在看到的这个界面 Workspaces 是一个工作空间管理 这里 我们选择进入 我的工作空间 之后 我们所有的接口请求 就都是在这一块完成的 Collection…

ubuntu中安装VMware Tools,实现Windows文件拖入Ubuntu

ubantu作为一款非常好用的Linux发行版本&#xff0c;深受广大开发者的喜爱&#x1f603;&#xff0c;为了开发的方便&#xff0c;人们常常在windows电脑中安装VMware虚拟机来运行Linux系统&#xff0c;我们时常会遇到这样一种情况&#xff1a;无法互传虚拟机与主机文件。 原因就…

终端连接工具Tabby的下载、安装与配置

目录 一、终端连接工具Tabby的下载1.1、Tabby的下载地址1.2、Tabby的下载步骤 二、终端连接工具Tabby的安装三、终端连接工具Tabby的SSH连接四、终端连接工具Tabby的SFTP 传输工具4.1、服务器上的文件传输到本地电脑4.2、本地电脑的文件传输到服务器 五、终端连接工具Tabby的设…

基于网络爬虫和SpringBoot框架的晋江文学小说小型网站项目

一、Python网路爬虫技术的设计与实现 Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架&#xff0c;常可以应用在包括数据挖掘&#xff0c;信息处理或存储历史数据等一系列的程序中。项目中&#xff0c;主要采取Scrapy框架实现一个爬虫&#xff0c;抓…

JavaSE3(4/26)

目录 1.线程的状态 2.线程安全问题 3.synchronized的具体用法 4. 1.线程的状态 首先明白进程的状态:就绪或者阻塞 上述说的就绪和阻塞其实是针对系统中的线程状态(PCB) Java中对于Thread类中的线程的状态进行了进一步的细化 NEW: Thread对象有了,但是线程还没有被执行 TERMI…

RabbitMQ之介绍以及安装

1.1 MQ的相关概念 1.1.1 什么是MQ ​ MQ&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO先入先出&#xff0c;只不过队列中存放的内容是message而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中&#xff0c;MQ…

摄影tips

一、基础知识 相机挡位 A档就是全自动模式或称场景智能自动模式&#xff0c;该拍摄模式下&#xff0c;相机会根据光线和你所拍摄的对象等场景环境自行设置快门、光圈等参数&#xff0c;你不需要调整任何参数&#xff0c;拿起相机对焦按快门就行&#xff0c;也就是AUTO模式。虽…

opengauss编译和使用oracle_fdw

opengauss虽然继承自postgresql9.2&#xff0c;但由于做了魔改&#xff0c;网上通用的从oracle_fdw源码编译安装到postgresql的方法&#xff0c;是否成功的应用到opengauss&#xff0c;并不一定&#xff0c;今天试了一下&#xff0c;参照opengauss官网文档&#xff08;其实写的…

Spring Bean的作用域及生命周期

目录 前言&#xff1a; Bean的作用域&#xff08;Scope&#xff09; 单例模式 原型模式&#xff08;多例作用域&#xff09; 请求作用域&#xff08;request&#xff09; 会话作用域 全局作用域 网络长连接 Spring执行流程 Bean的生命周期 测试 小结&#xff1a; 前…

多模态论文串讲:ALBEF VLMo BLIP CoCa Beit V3

文章目录 前言ALBEF:Align before Fuse: Vision and Language Representation Learning with Momentum Distillation(2021-10)VLMO: Unified Vision-Language Pre-Training with Mixture-of-Modality-Experts(2021-11)relatedmethod BLIP&#xff1a;Bootstrapping Language-Im…

【贴片SD Card介绍】贴片SD Card (LEILONG雷龙科技)

有幸申请到了雷龙科技代理的 贴片 SD Card (SD NAND) 样品&#xff0c;做出测试&#xff0c;分享一下。 型号&#xff1a;CSNP32GCR01-BOW&#xff1b;CSNP4GCR01-BOW 生产方&#xff1a;CS创世半导体 由于是第一次使用贴片类型的 SD Card &#xff0c;可能文章会有较多疏忽。…

【Git】Windows Git和TortoiseGit安装教程(Git2.23.0、TortoiseGit2.8.0、语言包2.8.0)

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

eletron+react+antd+node开发桌面小程序并打包(electron-packager+electron-builder)

首先罗列一下项目中用到的技术&#xff1a; electron, react&#xff0c;antd, typescript, node&#xff0c;及打包命令&#xff1a;pkg&#xff0c;electron-packager&#xff0c;electron-builder及child_process实现多进程 需求&#xff1a;开发一个桌面应用&#xff0c;左…

前端架构师-week3-脚手架执行准备过程实现

目录​​​​​​​​​​​​​​ 脚手架框架代码拆包 import-local应用 检查版本号功能开发&#xff08;require加载资源类型讲解 npmlog封装&#xff09; 最低Node版本检查功能开发 root 账号启动检查和自动降级功能开发 用户主目录检查功能开发 入参检查和 debug…

华为OD机试真题(Java),火星文计算(100%通过+复盘思路)

一、题目描述 已知火星人使用的运算符为#、$&#xff0c;其与地球人的等价公式如下&#xff1a; x#y 2*x3*y4 x$y 3*xy2 其中x、y是无符号整数&#xff1b;地球人公式按C语言规则计算&#xff1b;火星人公式中&#xff0c;$的优先级高于#&#xff0c;相同的运算符&#x…

数字船厂信息化整体解决方案(ppt可编辑)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除 数字船厂建设思路 智慧船厂将以信息化为基础、以数据为纽带、以制造为核心、以管理为载体打造新型智慧园区&#xff0c;该智慧园区整合了船厂的安全、环保、能源、安防、应急…

基于 JavaWeb 的用户报名审核平台项目

目录 一、项目的需求&#xff1a; 二、项目的思路流程&#xff1a; 三、项目的框架&#xff08;基于JavaWeb&#xff09;&#xff1a; 四、项目的详细搭建 1、数据库--建库建表 2、JavaBean编写&#xff08;以Status.java为例&#xff09; 3、Dao层&#xff08;StatusDao…

Linux系统与shell编程第一节课

目录 1.1 Linux发展历史 1.2 什么是linux&#xff1f; 1.3 Linux的发行版 Host-Only&#xff08;仅主机模式&#xff09; windows开发 linux服务 区块链&#xff0c; 特点&#xff1a;稳定&#xff0c;安全&#xff0c;可移植性&#xff0c;低资源消耗&#xff0c;开源软…