G1调优分析

article/2025/9/1 9:32:31

目录

1、畅想GC的目标

2、jvm调优的目标

3、GC调优时机

4、垃圾收集器的选择

5、G1调优策略

6、G1垃圾收集实践

6.1、JVM自动选择垃圾收集器

6.2、G1垃圾收集

6.3、GC日志分析

7、小结


前言
c++和java之间有一堵由内存动态分配和垃圾收集技术所围成的墙,墙外面的人想进去墙里面的人想出来。

1、畅想GC的目标

    詹姆斯· 高斯林  (James Gosling)是一名软件专家,喊出了口号:“一次编写,到处乱跑。”
他在1995年写java这门编程语言的时候,可能并没有想到java会如此广泛的应用于web开发,没有意识到要进行更多的web交互场景,应用对停顿时间要求是如此的严格,否则在刚开始设计垃圾回收的时候就不会粗暴的直接将应用线程停掉了。这个在现在来看是不太能接受的,随着jdk往上发展,web的高并发,交互场景的越来越频繁, 所以要追求低停顿和高吞吐量成了程序员们的追求,所以垃圾收集器就需要与时俱进的进行不断的优化,再优化,直到没有停顿。
以至于出现了Z-GC,Z也不知道是不是zero的意思,代表着程序员们的极致追求,没有停顿时间。
The Z Garbage Collector (ZGC) is a scalable low latency garbage collector. 
ZGC performs all expensive work concurrently, without stopping the execution of application threads for more than 10ms, 
which makes is suitable for applications which require low latency and/or use a very large heap (multi-terabytes).
The Z Garbage Collector is available as an experimental feature, 
and is enabled with the command-line options-XX:+UnlockExperimentalVMOptions -XX:+UseZGC.

ZGC的官网描述:Z-GC目标:能够让应用gc停顿的时间低于:10ms,适用于更大堆。

参考资料:Z-Gabage: https://docs.oracle.com/en/java/javase/11/gctuning/z-garbage-collector1.html#GUID-A5A42691-095E-47BA-B6DC-FB4E5FAA43D0

2、jvm调优的目标

随着互联网的web应用流量激增,堆内存空间的不断增大,从官方垃圾收集器的一步步优化之路不难发现,程序员对JVM 的垃圾收集追求的目标在于以下三点:
  • 吞吐量- Throughput;运行用户代码时间/(运行用户代码时间+垃圾收集时间)
  • 停顿时间-P auseTime;垃圾收集器进行 垃圾回收中断应用执行响应的时间
  • GC的频率-GCTimes;一般不做硬性要求,能接受一定程度的younggc,但一定要避免full-gc;
停顿时间越短就越适合需要和用户交互的程序,良好的响应速度能提升用户体验;
高吞吐量则可以高效地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。
吞吐量和停顿时间也是评价一个垃圾收集器优劣的指标。
可能JVM对垃圾收集器追求的终极目标是:没有停顿时间且拥有高吞吐量。
遗憾的是,目前还没有这样一款垃圾收集器问世,当然,也不是所有的应用都是追求停顿时间,可能有的不在乎时间而在乎吞吐量,所以我们目前所能做到的就是不断调优,根据业务场景找到适应各自的项目需求的垃圾收集器,让上面的三个主要的目标达到最优。

3、GC调优时机

什么时候才需要调优?GC到底影响什么?GC的常见症状?
首先一定不是无聊,天马行空的改参数,那样反而适得其反。
例如 GC停顿导致 常见的问题的症状
  • 系统CPU飙升很快;
    • 系统运行的响应时间长,接口响应超时;
    • 网站经常不定期出现:长时间没有响应的现象。
    • gc次数太多,用户线程代码执行受影响,cpu使用会高?
  • 内存的使用率逐渐增大,不够用了;

4、垃圾收集器的选择

jvm调优:如何调优才能实现我们的目标 呢,首先是垃圾收集器的选择。
首先要明确,jvm的调优没有万能公式,每个项目背景和要求不同,调优的策略和参数都不一样。
首先关于垃圾收集器的选择:并不是并发度越高就越好的,停顿时间越短就越好。需要根据具体的情况来看。
官网垃圾收集器的选择标准: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#sthref28
Selecting a Collector
首先让jvm来自动选择,不能满足;
调整堆的大小,减少垃圾回收次数;
Unless your application has rather strict pause time requirements, first run your application and allow the VM to select a collector. If necessary, adjust the heap size to improve performance. 
如果仍然不能满足:
If the performance still does not meet your goals, then use the following guidelines as a starting point for selecting a collector.内存小于100m,可以选择serial收集器;
* If the application has a small data set (up to approximately 100 MB), then
select the serial collector with the option 
-XX:+UseSerialGC.单线程,使用serial;
* If the application will be run on a single processor and there are no pause time requirements, then let the VM select the collector, or select the serial collector with the option-XX:+UseSerialGC.没有停顿时间的要求,关注吞吐量,选择并行收集器;
* If (a) peak application performance is the first priority and (b) there are no pause time requirements or pauses of 1 second or longer are acceptable, then let the VM select the collector, or select the parallel collector with-XX:+UseParallelGC.关注停顿时间的要求,可以选择G1;
* If response time is more important than overall throughput and garbage collection pauses must be kept shorter than approximately 1 second, then select the concurrent collector with -XX:+UseConcMarkSweepGC or-XX:+UseG1GC.

根据官网推荐,垃圾收集器的选择标准总结如下:

  1. 优先调整堆的大小让服务器jvm自己来选择一个合适的垃圾收集器;
  2. 如果内存小于100M,使用串行收集器;
  3. 如果是单核,并且没有停顿时间要求,使用串行或JVM自己选
  4. 如果允许停顿时间超过1秒,选择并行CMS或JVM自己选;
  5. 如果响应时间最重要,并且不能超过1秒,使用并发收集器G1;
从结论可以看出:选择一个合适的垃圾收集需要根据系统的要求:
  • 比如cpu的核心数:如果是单核cpu,选择并发垃圾收集器也没有用,因为单核还是串行的,线程的切换反而降低了垃圾收集的效率;
  • 堆的大小:类似G1垃圾收集,它的内存布局让它更适合大堆内存的收集,而小堆内存串行和CMS就能有比较高的性能;
  • 是否关注停顿时间:如果不关注停顿时间关注吞吐量,串行和CMS就能提供很好的性能,也并不是G1就是最好的;

5、G1调优策略

官方也给出了G1调优的一些建议指南: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations
  • (1)不要手动设置新生代和老年代的大小,只要设置整个堆的大小
    • G1收集器在运行过程中,会自己调整新生代和老年代的大小 其实是通过自动调整young代的大小 来调整对象晋升的速度,从而达到为收集器设置的暂停时间目标,如果手动设置了大小就意味着放弃了G1的自动调优, 破坏了停顿时间策略;
  • (2) 不断调优暂停时间;不要太严格
    • 一般情况下这个值设置到100ms或者200ms都是可以的(不同情况下会不一样),但如果设置成50ms就不太合理。
    • 暂停时间设置的太短,就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。
    • 所以对这个参数的调优是一个持续 的过程,逐步调整到最佳状态。暂停时间只是一个目标,并不能总是得到满足。
  • (3)使用-XX:ConcGCThreads=n来增加标记线程的数量
    • IHOP如果阀值设置过高,可能会遇到转移失败的风险,比如对象进行转移时空间不足。如果阀值设置过低,就会使标 记周期运行过于频繁,并且有可能混合收集期回收不到空间。 IHOP值如果设置合理,但是在并发周期时间过长时,可以尝试增加并发线程数,调高ConcGCThreads。
  • (4)MixedGC调优
    • -XX: InitiatingHeapOccupancyPercent=45 :触发并发标记的堆内存使用占比;
    • -XX:G1MixedGCLiveThresholdPercent
    • -XX:G1MixedGCCountTarger
    • -XX:G1OldCSetRegionThresholdPercent
  • (5)条件允许的情况下,适当增加堆内存大小

6、G1垃圾收集实践

一般如果发现gc频繁,或者gc停顿时间长不可接受,我们就需要对gc的参数进行调整,然后通过日志,调整参数,达到一个GC停顿时间和吞吐量的最佳的状态,我们将用以下代码来模拟查看堆区的gc日志来进一步了解jvm各垃圾收集的工作过程,由于CMS之前分析过,这里不在赘述,主要分析下G1收集器。

6.1、JVM自动选择垃圾收集器

首先我们自己不设置垃圾收集器,让JVM自己来为我们选择,因为官方推荐这么做,当不知道如何选择的时候可以把这个权限交给JVM,JVM会默认的选择一个垃圾回收器,用下面一小段代码来不断产生垃圾,看垃圾收集器的作用及日志。
public class HeapOomGCTest {public static String heapOOMtest() throws InterruptedException {List<Person> list = new ArrayList<Person>();while (true) {list.add(new Person());System.out.println("add Person success~");Thread.sleep(10);}}public static void main(String[] args) throws InterruptedException {heapOOMtest();}
}

设置参数如下:

-Xms30m -Xmx30m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:JvmAutoSelectGC.log

JvmAutoSelectGC.log日志解读:
Java HotSpot(TM) 64-Bit Server VM (25.201-b09) for bsd-amd64 JRE (1.8.0_201-b09), built on Dec 15 2018 18:35:23 by "java_re" with gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Memory: 4k page, physical 16777216k(651656k free)/proc/meminfo:CommandLine flags: -XX:InitialHeapSize=31457280 -XX:MaxHeapSize=31457280 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC2020-11-22T09:05:50.054-0800: 10.188: [GC (Allocation Failure) [PSYoungGen: 8192K->1008K(9216K)] 8192K->1276K(29696K),0.0019565 secs] [Times: user=0.00 sys=0.01, real=0.00 secs]

日志具体内容分析:

-XX:+UseParallelGC :通过日志发现在没有设置GC垃圾收集器的情况下, JDK1.8默认使用的垃圾收集器:ParallerGC = ParallerScavge +  ParallerOld
GC:表明进行了一次垃圾回收,前面没有Full修饰,PSYoungGen表明这是一次新生代的Minor GC,这里不管是新生代还是老年代都会STW。
Allocation Failure:表明本次引起GC的原因是因为在年轻代中没有足够的空间能够存储新的数据了。
8192K->1008K(9216K):(单位是KB)三个参数分别为:GC前该内存区域(这里是年轻代)使用容量,GC后该内存区域使用容量,该内存区域总容量。
因为我设置的总堆大小为30M=30720kb,-XX:NewRatio=2,出去其他的内存占用,所以新生代Eden区的总容量为:9216kb
0.0019565 secs:该内存区域GC耗时,单位是秒
8192K->1276K(29696K):三个参数分别为:堆区垃圾回收前的大小,堆区垃圾回收后的大小,堆区总大小。
[Times: user=0.00 sys=0.01, real=0.00 secs]:分别表示用户态耗时,内核态耗时和总耗时

6.2、G1垃圾收集

参数设置如下:
-Xms500m -Xmx500m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseG1GC -XX:MaxGCPauseMillis=15 -Xloggc:G1-gc.log

CommandLine flags: -XX:CMSInitiatingOccupancyFraction=30 -XX:InitialHeapSize=5242880 -XX:MaxHeapSize=5242880 -XX:+PrintGC 
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC #使用 G1垃圾收集;
# 什么时候发生的GC,相对的时间刻,GC发生的区域young,总共花费的时间,0.00478s,
2020-11-22T13:45:42.218-0800: 0.196: [GC pause (G1 Evacuation Pause) (young), 0.0018535 secs]# 表示8个垃圾回收线程,并行的时间[Parallel Time: 1.2 ms, GC Workers: 8]# GC线程开始相对于上面的0.196的时间刻[GC Worker Start (ms): Min: 122.3, Avg: 122.5, Max: 123.0, Diff: 0.7][Ext Root Scanning (ms): Min: 0.0, Avg: 0.2, Max: 0.9, Diff: 0.9, Sum: 1.9][Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0][Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0][Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0][Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0][Object Copy (ms): Min: 0.0, Avg: 0.2, Max: 0.4, Diff: 0.4, Sum: 1.8][Termination (ms): Min: 0.0, Avg: 0.4, Max: 0.5, Diff: 0.5, Sum: 3.0][Termination Attempts: Min: 1, Avg: 1.8, Max: 4, Diff: 3, Sum: 14][GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1][GC Worker Total (ms): Min: 0.3, Avg: 0.8, Max: 1.1, Diff: 0.8, Sum: 6.8][GC Worker End (ms): Min: 123.3, Avg: 123.4, Max: 123.5, Diff: 0.1][Code Root Fixup: 0.0 ms][Code Root Purge: 0.0 ms][Clear CT: 0.1 ms][Other: 0.5 ms][Choose CSet: 0.0 ms][Ref Proc: 0.3 ms][Ref Enq: 0.0 ms][Redirty Cards: 0.2 ms][Humongous Register: 0.0 ms][Humongous Reclaim: 0.0 ms][Free CSet: 0.0 ms][Eden: 1024.0K(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->1024.0K Heap: 1024.0K(6144.0K)->536.1K(6144.0K)][Times: user=0.01 sys=0.00, real=0.00 secs]
G1-GC.log部分日志截取如下:

从上面的日志来看,其日志格式复杂了很多,可以参考G1日志详细解读:https://blogs.oracle.com/poonam/understanding-g1-gc-logs

6.3、GC日志分析

6.3.1、本地工具查看:gc-viewer
使用命令运行:
java -jar gcviewer-1.36-SNAPSHOT.jar  

运行这个工具jar包,打开我们刚刚生成的G1-GC.log文件,我们就可以看见jvm调优的几个核心指标,其实从工具我们也可以清楚的看到jvm的gc调优关注的是什么,调的是什么,停顿时间-吞吐量-GC频率

  
可以发现,通过此工具清楚的看到 g1发生gc的详情, 停顿耗时,gc次数,吞吐量都一目了然,之前我们的设置参数如下,设置的比较小,这样效果比较明显。
-Xms5m -Xmx5m -XX:+PrintGCDetails -XX:CMSInitiatingOccupancyFraction=30   -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:MaxGCPauseMillis=5 -XX:+UseG1GC  -Xloggc:G1-GC.log

我们发现其核心指标如下:

吞吐量
最小停顿时间
平均停顿时间
最大停顿时间
gc次数
97.25
0.00048
0.00254
0.00671
13
从这几个参数我们就可以看出停顿时间,吞吐量和gc的次数是否符合我们的要求,如果不符合我们可以继续调整参数。
调整方案:
  1. 如果gc频次高,我们可以适当的增加堆内存,这样可能会增加gc的停顿时间;
  2. 然后我们可以适当的控制减小gc的停顿时间,但不要太严格;如果频次还是高;
  3. 可以修改触发G1垃圾回收的阈值 -XX:InitialHeapOccupacyPersent,默认是45%,可以适当的提高;
最终达到频次,停顿时间和吞吐量的一个最优值;
6.3.2、在线工具:GCeasy工具
这个工具也可以看到gc的详细过程及日志情况,还可以比较不同的垃圾收集器的吞吐量和停顿时间,非常方便,但是在线的工具需要注意安全性。
官网地址 : https://gceasy.io
打开我们刚刚生成的G1-gc.log日志,从官网的显示也可以看出gc调优的三个重要指标: 吞吐量 + 停顿时间 + gc频次
从结果可以清晰的看到jvm调优的三个核心指标的数据,不同工具好像统计出的有一定的差别,所以我们可以通过这些工具来帮助我们更好的分析gc日志。

7、小结

GC的垃圾收集器的参数和选择都不唯一,需要根据项目的场景及硬件条件作出选择,适合的就是最好的,没有银弹。
  • gc调优核心指标
    • 吞吐量 — throughtput
    • 停顿时间 —pause time
    • gc频率 — gc times
  • GC日志查看工具:
    • GCeasy:在线工具;
    • GCviewer:本地工具;java -jar gc-viewer.jar
OK---望着大河弯弯,终于敢放胆,嬉皮笑脸面对,人生的难。
水滴石穿,积少成多。学习笔记,内容简单,用于复习,梳理巩固。
参考资料:
《深入理解jvm虚拟机》
Z-Gabage: https://docs.oracle.com/en/java/javase/11/gctuning/z-garbage-collector1.html#GUID-A5A42691-095E-47BA-B6DC-FB4E5FAA43D0
G1日志详细解读: https://blogs.oracle.com/poonam/understanding-g1-gc-logs
G1调优的一些建议指南: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations

http://chatgpt.dhexx.cn/article/vIs1isBG.shtml

相关文章

JVM垃圾回收器G1详解

1、概述 在我们应用程序所应对的业务越来越庞大、复杂&#xff0c;用户越来越多&#xff0c;没有GC就不能保证应用程序正常进行&#xff0c;而经常造成STW的GC又跟不上实际的需求&#xff0c;我们需要不断地尝试对GC进行优化。G1&#xff08;Garbage-First&#xff09;垃圾回收…

G1垃圾回收器

1、最大堆大小 G1管理的最大堆大小为64G。每个Region的大小通过 -XX:G1HeapRegionSize 来设置&#xff0c;大小为 1~32MB &#xff0c;默认最多可以有2048个Region&#xff0c;G1能管理的最大堆内存是 32MB*204864G 。 使用G1垃圾回收器最小堆内存应为 1MB*20482GB &#xff…

ZGC都出来了,你还不懂G1?

概念 G1&#xff08;Garbage-First Collector&#xff09;是一种垃圾回收算法&#xff0c;最早在JDK 6 Update 14中作为实验性功能加入&#xff0c;并在JDK 7 Update 4正式JDK&#xff0c;之后在JDK 9 中成为默认垃圾回收算法&#xff0c;在JDK 10中优化了Full GC性能。 G1是一…

G1详解

一 G1收集器 g1收集器是一个面向服务端的垃圾收集器适用于多核处理器、大内存容量的服务端系统。 它满足短时间gc停顿的同时达到一个较高的吞吐量。 JDK7以上版本适用 “ 先介绍两个概念&#xff1a;吞吐量和响应能力&#xff0c;响应能力和吞吐量是评价一个系统的两个重要指标…

G1垃圾回收器详解

文章目录 前言一、思考问题二、官方文档三、基本介绍四、G1的内存模型五、G1的标记过程六、G1的垃圾回收1、G1过程梳理2、Young GC3、Mixed GC4、Full GC 七、参数介绍八、分析各阶段触发时机根据GC日志分析Young GC的触发时机根据GC日志分析并发标记的触发时机根据GC日志分析M…

G1 GC

G1GC基本概念 G1 GC可以看做是CMS GC的重大升级改造G1 GC的全称是Garbage-First&#xff0c;意为垃圾优先&#xff0c;哪一块的垃圾最多就优先清理他。G1 GC最主要的设计目标是&#xff1a;将STW停顿的时间和分布&#xff0c;变成可预期且可配置的。&#xff08;默认200ms&…

G1垃圾回收器-----基本知识及原理解析

G1介绍&#xff08;Garbage first&#xff09; G1主要面向的是服务端的垃圾回收器。在G1之前&#xff0c;JVM的主要垃圾回收器采用的是物理分代的思想&#xff0c;将内存区域严格的划分成年轻代&#xff08;young GC&#xff09;和老年代&#xff08;major GC&#xff09;&…

可控硅BT136典型应用电路

1&#xff0e;双向可控硅SCR可根据负载功率大小选择97A6&#xff08;约1A&#xff09;、TLC336A&#xff08;约3A&#xff09;、BT136-500D&#xff08;约6A&#xff09;中的一个&#xff0c;选择原则是触发电流要小于25mA。 2&#xff0e;C4取值在0.1 ~ 0.47uF之间&#xff0c…

全能电子地图实时路况_全能SUV与城市SUV的区别在哪?日产奇骏对比本田皓影

在如今的市场中&#xff0c;越来越多的车企将重点放在SUV车型中&#xff0c;尤其今年大量家用SUV涌入市场&#xff0c;特别是紧凑级SUV将这片市场瓜分的“支离破碎”。即使车型越来越多&#xff0c;市场被瓜分的越来越小&#xff0c;但是在很多消费者心中&#xff0c;几个主流品…

音质卓越颜值在线,五款高人气头戴式HIFI音质蓝牙耳机排名

随着我们生活水平的逐渐提高,我们对科技产品的要求也就越来越高,就拿耳机来说,对于很多上班族或是年轻人耳机绝对是出门或是旅行的必备品之一,没有音乐的路途那绝对是缺少了灵魂,那自然耳机的地位也就越发的重要。无线,音效,小巧,这几个因素也就成为了我们选择耳机的最…

服务器购买及宝塔部署环境说明(阿里云为例)

服务器相关知识 为什么程序员都需要自己的服务器&#xff1f; 1、你作为一个程序员&#xff0c;必须要发部自己的网站和项目&#xff01; 2、联系Linux的操作。 3、自己的远程仓库、远程数据库、远程tomcat…都可以搭建在服务器上 4、联系&#xff0c;Linux进行任意的环境…

Linux学习一概述和环境搭建(入门概述,环境搭建,走近Linux系统)

此文档学习来自b站遇见狂神说&#xff0c;自己做的学习笔记整合。 狂神说Linux 继续Java全栈开发的Linux&#xff0c;而不是运维级别&#xff01; 我们为什么要在这个时间学习Linux&#xff1f;Java全栈开发的我们要掌握哪些知识&#xff1f;需要准备什么工作&#xff1f; J…

CK6855M1蓝牙离线语音识别灯控模组使用说明书

CK6855M1蓝牙离线语音识别灯控模组使用说明书 一、功能说明 CK6855M1模块是一款专为灯具照明产品设计的离线蓝牙语音识别模组。模组支持红外遥控接收&#xff0c;支持RGBWY灯控制&#xff0c;支持无极调光&#xff0c;支持AD按键调灯以及音频上下曲的控制&#xff0c;支持5.1…

为什么P2P模式下载的人越多速度越快,为什么P2P伤害机械硬盘

台风来临前的夜晚&#xff0c;有点激动不想睡觉&#xff0c;看了几个电影&#xff0c;日本恐怖片&#xff0c;台风雨夜&#xff0c;非常不错&#xff0c;P2P很流畅&#xff0c;观察IP地址大量也是附近的&#xff0c;江浙沪&#xff0c;难道也都在迎台风看电影&#xff1f; 大家…

伊人在线高清视频 index.php,《天元》“畅音阁”首发飞行技能视频

直面一款网游给人感觉的优异度最大成分中的重中之重就是第一感——“视听”印象。一直以来&#xff0c;游戏音乐以及画面成分的优异华丽与否直接关系到了玩家对于此款游戏的好感度&#xff0c;无可厚非。而《天元》特别针对于此&#xff0c;倾情打造出一篇关于对于其所有“视听…

迅雷跃居全球BT市场第一

据torrentfreak报道&#xff0c;根据早些时候海盗湾公布的一些数据表明&#xff0c;全球BT软件的使用者&#xff0c;大约有三分之一来自中国&#xff0c;而来自美国的仅有8%&#xff0c;迅雷成为全球BitTorrent市场份额最大的客户端。 迅雷本身并不是一个专门使用P2P的BT客户端…

11个资源强大的网站!知乎超20万人强烈推荐,再也不怕资源难找

在我们日常工作学习中难免就需要在网站搜索资料&#xff0c;这时候一定需要一个能够帮你搜索一切你想要的资源&#xff0c;从而为你剩下一大半时间&#xff0c;那么今天为大家整理了11个超级好用的黑科技资源搜索网站&#xff0c;帮你解决因为上网找不到合适的资源而发愁&#…

Linux6.8搭建sftp服务

最近因公司工作需要用到sftp服务器&#xff0c;参考网上各种方法&#xff0c;但被网上各种方法尤其是权限设置问题搞得晕头转向&#xff0c;现在将自己搭建过程总结了一下&#xff0c;提供给大家希望有所帮助。 sftp是Secure FileTransfer Protocol的缩写&#xff0c;安全文件传…

107-161JS

107-161 target事件委托正则表达式捕获exec特性 this指向改变this指向ES6定义变量ES6箭头函数ES6解构赋值ES6展开运算符ES6模块化初识面向对象创建对象构造函数注意问题面向对象的原型ES6-Class面向对象继承ES6继承Aajaxajax同步异步请求方式1ajax的封装回调地狱promise基础语法…

fastjson与net.sf.json区别

在现在的开发当中&#xff0c; 绝大多数引用阿里巴巴的fastjson。 当然net.sf.json同样可以使用。 一、引入com.alibaba.fastjson包 <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency><groupId>com.alibaba</groupId>…