目录
一、垃圾标记算法
1.1、垃圾标记阶段:对象存活判断
1.2、引用计数算法
1.3、可达性分析算法
1.4、GC Roots
二、对象的finalization机制
2.1、生存还是死亡?
三、查看GC Roots
3.1、使用MAT查看
四、使用JProfiler分析OOM
五、清除阶段算法
5.1、标记清除阶段
5.2、标记-清除(Mark-Sweep)算法
5.3、复制(copying)算法
5.4、标记-压缩(Mark-compact)算法
5.5、三种算法的对比
六、分代收集算法
七、增量收集算法
八、分区算法
一、垃圾标记算法
1.1、垃圾标记阶段:对象存活判断
1、在堆里面存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是已经死亡的对象。只有被标记为已经死亡的对象 ,GC才会在执行垃圾回收时,释放掉其占用的内存空间,因此这个过程可以被称为标记阶段。
2、在JVM中如何标记一个死亡对象?当一个对象已经不再被任何存活对象继续引用时,就可以宣判为已经死亡。
3、判断对象存活一般有两种方式:引用计数算法和可达性分析算法 。
1.2、引用计数算法
1、引用计数算法(Reference Counting)比较简单,对每个对象保存一个整型的引用计数器属性。用于记录对象被引用的情况。
2、对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1;当引用失效时,引用计数器就减1。只要对象A的引用计数器的值为0,即表示对象A不可能再被使用,可进行回收。
3、优点:实现简单。垃圾对象便于辨识;判断效率高,回收没有延迟性 。
4、缺点:①、需要单独字段存储计数器,这样的做法增加了存储空间的开销。②、每次赋值都需要更新计数器,伴随着加法和减法操作,这增加了时间开销。③、引用计数器有一个严重的问题,即无法处理循环引用的情况。这是一个致命缺陷,导致Java的垃圾回收器没有使用这类算法。
参考代码:
参数设置:-XX:+PrintGCDetails
public class RefCountGCTest {
//占用5mb的内存
private byte[] bigSize = new byte[5 * 1024 * 1024];
Object reference = null;
public static void main(String[] args) {
RefCountGCTest refCountGCTest1 = new RefCountGCTest();
RefCountGCTest refCountGCTest2 = new RefCountGCTest();
refCountGCTest1.reference = refCountGCTest2;
refCountGCTest2.reference = refCountGCTest1;
refCountGCTest1 = null;
refCountGCTest2 = null;
//显示的执行垃圾回收行为
System.gc();
}
}
情况1:不显示调用gc()回收
情况2:显示调用gc()回收
总结:1、引用计数算法,是很多语言的资源回收选择,例如python,它更是同时支持引用计数和垃圾收集机制。2、具体那种算法最优要看场景,业界有大规模实践中仅保留引用计数机制,以提高吞吐量的尝试。3、Java并没有选择引用计数,是因为其存在一个基本的难题,也就是很难处理循环引用关系。4、解决办法:①、手动解除,即在合适的时机,解除引用关系。②、使用弱引用weakref,weakref是python提供的标准库,意在解决循环引用。
1.3、可达性分析算法
1、相对于引用计数算法,可达性分析算法不仅同样具备实现简单和执行高效等特点,更重要的是该算法可以有效地解决在引用计数算法中循环引用的问题,防止内存泄漏的发生。
2、相较于引用计数算法,可达性分析就是Java、C#选择的 。这种类型的垃圾收集通常也叫作追踪性垃圾收集(Tracing Garbage Collection)
3、所谓”GC roots“根集合就是一组必须活跃的引用。
4、基本思路:
①、可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达。
②、使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为引用链(reference Chain)。
③、如果目标对象没有任何引用链相连,则是不可达的,意味着该对象已经死亡,可以标记为垃圾对象。
④、在可达性分析算法中,只有能够被根对象集合直接或者间接连接的对象才是存活对象。
1.4、GC Roots
1、虚拟机栈中引用的对象,如各个线程被调用的方法中使用到的参数、局部变量等。
2、本地方法栈内JNI(通常说的本地方法)引用的对象。
3、方法区中类静态属性引用的对象。如Java类的引用类型静态变量
4、方法区中常量引用的对象。如字符串常量池(String Table)里的引用。
5、所有被同步锁synchronized持有的对象。
6、Java虚拟机内部引用。如基本数据类型对应的Class对象,一些常驻的异常对象(例如NullPointerException,OutOfMemoryError),系统类加载器。
7、反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。
8、除了固定的GC Roots集合以外,根据用户所选用的垃圾收集器以及当前回收的内存区域不同,还可以有其他对象”临时性“地加入,共同构成完整GC Roots集合。如:分代收集和局部回收(Partial GC)。
注 意:1、如果要使用可达性分析算法来判断内存是否可回收,那么分析工作必须在一个能保障一致性的快照中执行。这点不满足的话分析结果的准确性就无法保证。2、这点也是导致GC进行时必须”Stop The World“的一个重要原因。即使是号称(几乎)不会发生停顿的CMS收集器中,枚举根节点时也是必须要停顿的。
二、对象的finalization机制
1、当Java语言提供了对象终止(finalization )机制来允许开发人员提供对象被销毁之前的自定义处理逻辑 。
2、当垃圾回收器发现没有引用指向一个对象,即:垃圾回收此对象之前,总会先调用这个对象的finalize()方法。
3、finalize()方法允许在子类中被重写,用于在对象被回收时进行资源释放 。通常在这个方法中进行一些资源释放和清理工作,如关闭文件,套接字和数据库连接。
4、永远不要主动调用某个对象的finalize()方法,应该交给垃圾回收机制调用。原因:①、在finalize()时可能会导致对象复活。②、finalize()方法的执行时间是没有保障的,它完全由GC线程决定,极端情况下,若不发生GC,则fianlize()方法将没有执行机会。③、一个糟糕的finalize()会严重影响GC的性能。
5、从功能上来说,finalize()方法与C++中的析构函数比较相似,但是Java采用的是基于垃圾回收器的自动内存管理机制,所以finalize()方法本质上不同于C++中的析构函数。
6、由于finalize()方法的存在,虚拟机中的对象一般处于三种可能的状态 。
2.1、生存还是死亡?
1、如果从所有根节点都无法访问到某个对象,说明对象已经不再使用了。一般来说,此对象需要被回收。但事实上,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段。一个无法触及的对象有可能在某一个条件下“复活”自己 ,如果这样,那么对它的回收就是不合理的,为此,定义虚拟机中的对象可能的三种状态。
①、可触及的 :从根节点开始,可以达到这个对象。
②、可复活的 :对象的所有引用都被释放,但是对象有可能在finalize()中复活。
③、不可触及的 :对象finalize()被调用,并且没有复活,那么就会进入不可触及状态。不可触及的对象不可能被复活,因为finalize()只会被调用一次。
2、以上3种状态中,是由于finalize()方法的存在,进行的区分,只有在对象不可触及时才可以被回收。
参考代码:
public class CanReliveTest {
//类变量
public static CanReliveTest canReliveTest;
//重写finalize(),只能被调用一次
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("调用当前类重写finalize()");
//当前待回收的对象在finalize()方法中与引用链上的一个对象canReliveTest建立了联系
canReliveTest = this;
}
public static void main(String[] args) {
try {
canReliveTest = new CanReliveTest();
//对象第一次拯救自己
canReliveTest = null;
System.gc();
System.out.println("第一次gc调用");
Thread.sleep(2000);
if (canReliveTest == null){
System.out.println("canReliveTest is dead");
}else {
System.out.println("canReliveTest is still alive");
}
System.out.println("第二次gc调用");
canReliveTest = null;
System.gc();
Thread.sleep(2000);
if (canReliveTest == null){
System.out.println("canReliveTest is dead");
}else {
System.out.println("canReliveTest is still alive");
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
三、查看GC Roots
3.1、使用MAT查看
MAT是MemoryAnalyzer的简称,它是一款功能强大的Java堆内存分析器,用于查找内存泄漏以及查看内存消耗情况。是基于Eclipse开发的,是一款免费的性能分析工具
方式:使用JVisualVM生成dump文件
参考代码:
public class GCRootsTest {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList<>();
Date date = new Date();
for (int i = 0; i < 100; i++) {
arrayList.add(String.valueOf(i));
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("数据添加完成");
new Scanner(System.in).next();
arrayList = null;
date = null;
System.out.println("arrayList,date已清除");
new Scanner(System.in).next();
System.out.println("结束");
}
}
使用MAT进行查看保存的dump文件
四、使用JProfiler分析OOM
参考代码:
设置参数:-Xms15m -Xmx15m -XX:+HeapDumpOnOutOfMemoryError
public class HeapOOMTest {
//大小1MB
byte[] aByte = new byte[1 * 1024 * 1024];
public static void main(String[] args) {
ArrayList arrayList = new ArrayList<>();
int count = 0;
try {
while (true){
arrayList.add(new HeapOOMTest());
count++;
}
} catch (Exception e) {
System.out.println("合计:" + count);
throw new RuntimeException(e);
}
}
}
五、清除阶段算法
5.1、标记清除阶段
1、当成功区分出内存中存活对象和死亡对象后,GC接下来的任务就是执行垃圾回收,释放掉无用对象所占用的内存空间,以便有足够的可用内存空间为新对象分配内存。
2、目前在JVM中比较常见的三种垃圾收集算法是标记-清除算法、复制算法、标记-压缩算法
5.2、标记-清除(Mark-Sweep)算法
执行过程:
当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整个程序(也称为stop the world),然后进行两项工作,第一项则是标记,第二项则是清除:
①、标记:Collector从引用根节点开始遍历,标记所有被引用的对象。一般是在对象的Header中记录为可达对象。
②、清除:Collector对堆内存从头到尾进行线性的遍历,如果发现某个对象在其Header中没有标记为可达对象,则将其回收。
缺点: ①、效率不高。②、在进行GC的时候,需要停止整个应用程序,导致用户体验差。③、这种方式清理出来的空闲内存是不连续的,产生内存碎片。需要维护一个空闲列表。
什么是清除?
这里的清除并不是置空,而是把需要清除的对象地址保存在空闲的地址列表里。下次需要新对象需要加载时,判断垃圾的位置空间是否足够,如果够,就存放。
5.3、复制(copying)算法
将活着的内存空间分为两块,每次只使用其中一块,在垃圾回收时将正在使用的内存中的存活对象复制到未被使用的内存块中,之后清除正在使用的内存块中,之后清除正在使用的内存块中的所有对象,交换两个内存的角色,最后完成垃圾回收。
优点:
①、没有标记和清除过程,实现简单,运行高效。
②、复制过去以后保证空间的连续性,不会出现“碎片”问题。
缺点:
①、需要两倍的内存空间。
②、对于G1这种拆分成为大量region的GC,复制而不是移动,意味着GC需要维护region之间对象引用关系,不管是内存占用或者时间开销也不小。
注意:
如果系统中的垃圾对象很多,复制算法不会很理想。因为复制算法需要复制的存活对象数量并不会太大,或者非常低才行。
应用场景:
在新生代,对常规应用的垃圾回收,一次通常可以回收70%到99%的内存空间。回收性价比很高,所以现在的商业虚拟机都是用这种收集算法回收新生代。
5.4、标记-压缩(Mark-compact)算法
1、标记-压缩算法的最终结果等同于标记-清除算法执行完成后,再进行一次内存碎片整理,因此,也可以把它称为标记-清除-压缩算法。
2、二者的本质差异在于标记-清除算法是一种非移动式的回收算法,标记-压缩是移动式的。是否移动回收后的存活对象是一项优缺点并存的风险决策。
3、标记的存活对象将会被整理,按照内存地址依次排列,而未被标记内存会被清理。如此一来,当我们需要给新对象分配内存时,JVM只需要持有一个内存的起始地址就行,这比维护一个空闲表显然少很多开销。
执行过程:
第一阶段和标记清除算法一样,从根节点开始标记所有被引用对象。第二阶段将所有的存活对象压缩到内存的一端,按顺序排放。之后,清理边界外所有的空间。
优点:
①、消除了标记-清除算法当中,内存区域分散的缺点,我们需要给新对象分配内存时,JVM只需要持有一个内存起始地址即可。
②、消除了复制算法当中,内存减半的高额代价。
缺点:
①、从效率上来说,标记-整理算法要低于复制算法。
②、移动对象的同时,如果对象被其他对象引用,则需要调整引用的地址。
③、移动过程中,需要全程暂停用户应用程序。即STW
5.5、三种算法的对比
Mark-Sweep
Mark-Compact
Copying
速度
中等
最慢
最快
空间开销
少(但会堆积碎片)
少(不会堆积碎片)
通常需要活对象的2倍(不堆积碎片)
移动对象
否
是
是
六、分代收集算法
分代收集算法,是基于这样的一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集算法,以便提高回收效率。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点使用不同的回收算法,以提高垃圾回收效率。
在Java程序运行的过程中,会产生大量的对象,其中这些对象是业务信息相关,如Http请求中的Session对象,线程、Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长。但是还有一些对象,主要是程序运行过程中生成的临时变量,这些对象生命周期会比较短,如String对象,由于其不变类的特性。系统会产生大量的这些对象,有些对象甚至只用一次即可回收。
目前几乎所有的GC都是采用分代收集算法执行垃圾回收的。
以HotSpot中的CMS回收器为例,CMS是基于Mark-Sweep实现的,对于对象的回收率很高。而对于碎片问题,CMS采用基于Mark-Compact算法的Serial Old回收器作为补偿措施:当内存回收不佳(碎片导致的Concurrent Mode Failure时),将采用Serial Old执行Full GC以达到对老年代内存的整理。
分代的思想被现有的虚拟机广泛使用。几乎所有的垃圾回收器都区分新生代和老年代。
七、增量收集算法
上述现有的算法,在垃圾回收过程中,应用软件将处于一种Stop the World的状态。在Stop the World状态下,应用程序所有的线程都会挂机,暂停一切正常的工作,等待垃圾回收的完成。如果垃圾回收时间过长,应用程序会被挂起很久,将严重影响用户体验或者系统的稳定性。为了解决这个问题,即对实时垃圾收集算法的研究直接导致了增量收集(Incremental Collecting)算法的诞生。
基本思想:
如果一次性将所有的垃圾进行处理,需要造成系统长时间的停顿,那么就可以让垃圾收集线程和应用程序线程交替执行。每次,垃圾收集线程只收集一小片区域的内存空间,接着切换到应用程序线程。依次反复,直到垃圾收集完成 。
增量收集算法的基础仍是传统的标记-清除和复制算法。增量收集算法通过对线程间冲突的妥善处理,允许垃圾收集线程以分阶段的方式完成标记、清理或复制工作 。
缺点:
使用这种方式,由于在垃圾回收过程中,间断性地执行了应用程序代码,所以能减少系统的停顿时间。但是,因为线程切换和上下文转换的消耗,会使得垃圾回收的总体成本上升,造成系统吞吐量的下降 。
八、分区算法
一般来说,在相同条件下,堆空间越大,一次GC时所需要的时间就越长,有关GC产生的停顿也越长。为了更好地控制GC产生地停顿时间,将一块大的内存区域分割为多个小块,根据目标的停顿时间,每次合理地回收若干个小区间,而不是整个区间,从而减少一次GC所产生的停顿。
分代算法将按照对象的生命周期长短划分成两个部分,分区算法将整个空间划分成连续的不同小区间。
每个小区间都独立使用,独立回收。这种算法的好处是可以控制一次回收多少个小区间。
你可能感兴趣的:(JVM,java,jvm,算法)
初识redux
未命名小孩
前端知识 react js typescript
Redux是一个用于管理JavaScript应用程序状态的可预测状态容器核心概念1.单一数据源整个应用的状态被存储在一个单一的对象树(store)中,这个对象树位于唯一的store里。创建store:conststore=createStore(reducer)2.状态是只读的唯一改变状态的方法是触发一个action,action是一个描述状态变化的纯对象。这保证了所有的状态变化都是可追踪的。一个
题解 | #数组中出现次数超过一半的数字#哈希最简单的解法
2301_79125642
java
前端要转测试大佬们,我是软件工程专业的,毕业后又培训了半年前端,现在公司要我转软件测试,初中级都可以,学着麻烦吗?大概得多长时间?转转java凉面一个数组基本有序应该采用哪种排序方法为什么要有线程池,线程太多会怎么样??阻塞队列与普通队列的区别是?递归与非递归区别是什么?各自的优缺点?递归如何转为非递归题解|#数组中出现次数超过一半的数字#哈希最简单的解法classSolution{public:
实现能源高效利用、优化能源结构、降低碳排放的智慧能源开源了
AI服务老曹
能源 开源 人工智能 大数据 自动化 云计算
简介AI视频监控平台,是一款功能强大且简单易用的实时算法视频监控系统。愿景在最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,减少企业级应用约95%的开发成本,用户仅需在界面上简单操作,即可实现全视频的接入及布控。基础项目搭建地址参考:yihecode-server:本项目基于ai场景而开发,提供算法模型管理、摄像头管理、告警管理、数据统计等功能。系统根
如果 main 里面引入 axios ,然后引入 router ,而 router 里面也引入 axios,会不会重复
清风细雨_林木木
技术点 javascript 前端 开发语言
技术点备忘如果main里面引入axios,然后引入router,而router里面也引入axios,会不会重复不会重复的。虽然你在main中引入了axios,并且在router中也引入了axios,但引入的axios是同一个模块。JavaScript的模块系统是基于单例模式的,意思是每个模块只会被加载一次,之后的引用都会指向同一个实例。具体来说:当你在main.js中引入axios,它会在模块加载
【JVM系列】谈一谈JVM调优
goyeer(工蚁)
# JVM JAVA jvm
文章目录一、JVM调优概述二、JVM调优目标三、JVM定位瓶颈四、JVM内存调优1.调整堆内存大小2.调整新生代与老年代比例3.元空间(Metaspace)调优五、垃圾回收(GC)调优**1.选择合适的GC算法****2.优化GC参数**3.启用GC日志六、线程与锁优化七、调优后的验证八、注意事项一、JVM调优概述JVM调优是优化Java应用程序性能的关键环节,目的是通过调整JVM参数、优化垃圾回
基于Java的自助多张图片合成拼接实战
夜郎king
java Java多图片合成 Java图片合成实战
目录前言一、图片合成需求描述二、图片合成设计与实现1、编程语言2、基础数据准备3、图片合成流程4、图片合成实现三、总结前言在当今数字化时代,图像处理技术在各个领域都发挥着至关重要的作用。从社交媒体到电子商务,从在线教育到虚拟现实,图像的展示和处理方式直接影响着用户体验和信息传递的效率。而图片合成拼接技术作为图像处理中的一个重要分支,其应用范围广泛,需求也日益增长。在实际开发中,图片合成拼接的需求多
DeepSeek对AI领域的变革性影响分析报告
芝士AI吃鱼
人工智能 DeepSeek OpenAI
一、引言近年来,人工智能(AI)技术加速演进,而中国开源大模型DeepSeek的崛起,标志着全球AI竞争进入新阶段。其凭借低成本、高性能、开源生态三大核心优势,迅速成为行业焦点。本报告从技术、产业、投资、就业及未来趋势等维度,全面解析DeepSeek对AI领域的深远影响,为集团战略布局提供参考。二、技术突破:算法效率与成本革命架构创新:MOE与MLA技术优化DeepSeek采用混合专家系统(MoE
DeepSeek对AI发展的范式革新与推动:研究报告
芝士AI吃鱼
DeepSeek AI OpenAI LLM
DeepSeek对AI发展的范式革新与推动:研究报告一、技术范式的突破:从“算力堆砌”到“极致工程化”DeepSeek的成功标志着AI发展从依赖大规模算力投入向算法优化与工程效率的转变。其核心技术突破包括:低算力消耗的模型训练通过蒸馏训练策略、动态模型剪枝和稀疏训练,DeepSeek将训练成本降至OpenAI同类模型的1/10,同时保持性能可比甚至超越。例如,其训练成本仅558万美元,而OpenA
使用opencv实现深度学习的图片与视频的超分辨率
人工智能研究所
人工智能之计算机视觉 opencv 深度学习 视频超分辨率 图片超分辨率
图片超分辨率什么是视频与图片的超分辨率,总结一下便是给一张分辨率比较低的图片,进行超分辨率的处理后,生成比较清晰的高分辨率的图片,上图图片完美解释了超分辨率的过程,由于不同的算法不同,处理的结果也不相同,本期我们介绍一下如何进行图片的超分辨率的处理。·EDSR模型图像超分辨率EDSR:EnhancedDeepResidualNetworksforSingleImageSuper-Resolutio
Python之json模块的序列化和反序列化
如梦@_@
python基础
序列化:可以理解为压缩反序列化:可以理解为解压Python中序列化和反序列化其实就是一个正反两个过程。序列化就是将Python对象转化为json格式,因为Python对象只有Python语言能够识别,如果想把数据发给Java代码写的程序,那么就识别不了,所以就有一个中间的格式:json,Java中也是一样,就是将Java的数据类型转换成json格式。反序列化就是,Python接收数据的应该是Pyt
java使用递归获取geojson(json)数据
迷茫的小猿
java java json
需要导入的包:org.json-chargebee-1.0.jarpackageparse;importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.IOException;importjava.util.Arra
阅读Android源码的一些姿势
weixin_34405332
2019独角兽企业重金招聘Python工程师标准>>>前面吐槽了有没有必要阅读Android源码,后面觉得只吐槽不太好,还是应该多少弄点干货。需要说明的是,Android每个系统版本的源码都会有变动,而且代码中时不时Java和Native互相穿插,追求完全看透源码意义不大,把目的定在“理解代码设计的思路,弄清各个生命周期方法调用的顺序”比较实际。日常开发中怎么阅读源码找到正确的源码IDE是日常经常
OpenCV 简介
奇点创客
OpenCV
OpenCV(OpenSourceComputerVisionLibrary,开源计算机视觉库:http://opencv.org)是一个开放源代码库,其中包含数百种计算机视觉算法。本文档介绍所谓的OpenCV2.xAPI,与基于C的OpenCV1.xAPI相比,该API本质上是一套C++API(自OpenCV2.4发行以来,不推荐再使用CAPI,并且不使用“C”编译器进行测试)。OpenCV具有
OpenCV机器学习(1)人工神经网络 - 多层感知器类cv::ml::ANN_MLP
村北头的码农
OpenCV opencv 机器学习 人工智能
操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述cv::ml::ANN_MLP是OpenCV库中的一部分,用于实现人工神经网络-多层感知器(ArtificialNeuralNetwork-Multi-LayerPerceptron,ANN-MLP)。它提供了一种方式来创建和训练多层感知器模型,以解决分类、回归等
空间数据存储格式GeoJSON
guokanglun
WebGIS开发 前端
GeoJSON是一种用于表示地理信息的开放标准格式,广泛用于存储和交换地理空间数据。它基于JSON格式,因此易于理解和处理,尤其适用于Web和JavaScript环境中的地图应用。GeoJSON支持多种地理信息类型,如点、线、面、坐标系统等。GeoJSON基本结构GeoJSON文件本质上是一个JSON对象,通常包含以下几个主要部分:type:指定GeoJSON数据的类型。features:一个包含
java面试题:多线程交替打印数字
小猫猫猫◍˃ᵕ˂◍
java python 开发语言
面试题:多线程交替打印数字代码概述这个Java程序使用了三个线程(t1,t2,t3)和三个信号量(first,second,third)来实现交替打印数字1、2、3的功能。每个线程负责打印一个数字,并通过信号量来控制线程的执行顺序。代码结构信号量初始化:first,second,third三个信号量分别用于控制三个线程的执行顺序。初始时,first信号量的许可数为0,表示t1线程需要等待。线程定义
使用 Shiro 和 JPA 结合 MySQL 实现一个简易权限管理系统
Java猿_
mysql 数据库
1.项目设置首先,确保你的项目已经配置好Maven或Gradle依赖管理工具,并添加以下依赖:Maven依赖org.apache.shiroshiro-core1.9.0org.apache.shiroshiro-web1.9.0org.springframework.bootspring-boot-starter-data-jpamysqlmysql-connector-java8.0.26or
如何在Python中进行JSON数据的序列化和反序列化?
计算机学长大白
python python 开发语言
在Python中,JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。Python内置的json模块提供了简单易用的方法来实现数据的序列化和反序列化。下面将详细介绍如何在Python中进行JSON数据的序列化和反序列化,并给出具体的示例。1.序列化序列化是指将Python对象转换为JSON格式的字符串。json模块提供
Java 实现 Redis中的GEO数据结构
潇凝子潇
java redis 数据结构
Java实现Redis中的GEO数据结构LBS(基于位置信息服务(Location-BasedService,LBS))应用访问的数据是和人或物关联的一组经纬度信息,而且要能查询相邻的经纬度范围,GEO就非常适合应用在LBS服务的场景中importjava.util.ArrayList;importjava.util.List;//定义一个表示地理位置的类,用于存储地理位置的相关信息publicc
《DeepSeek训练算法:开启高效学习的新大门》
人工智能深度学习
在人工智能的浪潮中,大语言模型的发展日新月异。DeepSeek作为其中的佼佼者,凭借其独特的训练算法和高效的学习能力,吸引了众多目光。今天,就让我们深入探究DeepSeek训练算法的独特之处,以及它是如何保证模型实现高效学习的。一、独特的架构基础DeepSeek以Transformer架构为基石,但并非简单沿用,而是进行了深度创新。Transformer架构的核心是注意力机制,这让模型在处理序列数
每日一题——力扣——最长连续递增序列
爱编程的晖哥
力扣刷题 leetcode 算法 职场和发展
题目来源于力扣——画解算法:674.最长连续递增序列-最长连续递增序列-力扣(LeetCode)(leetcode-cn.com)给定一个未经排序的整数数组,找到最长且连续递增的子序列,并返回该序列的长度。连续递增的子序列可以由两个下标l和r(l
DeepSeek R1蒸馏版模型部署的实战教程
herosunly
DeepSeek从入门到精通 deepseek 大模型 人工智能 实战教程
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于大模型算法的研究与应用。曾担任百度千帆大模型比赛、BPAA算法大赛评委,编写微软OpenAI考试认证指导手册。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。授权多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法行业就业。希望和大家一起成长进步。
JAVA和Python的区别
草莓味的¥猪
语言 java python 开发语言
一、整体区别语法结构:Java是一种面向对象的编程语言,采用了类和对象的概念,需要使用大括号“{}”来定义代码块和方法。而Python是一种动态类型的编程语言,使用缩进来表示代码块的层级结构,不需要显式地定义类和对象。编程范式:Java是一种静态类型的编程语言,需要在编译时进行类型检查,并且必须声明变量的数据类型。Python是一种动态类型的编程语言,变量的数据类型是根据赋值而确定的,不需要显式声
LeetCode 第 211 场周赛 (哈希表、字符串(取模、枚举)、排序+最长上升子序列和、筛法求约数+并查集)
2401_84046816
程序员 leetcode 散列表 面试
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!for(inti=0;i
Java8适配的markdown转换html工具(FlexMark)
星极天下第一
前端 Java html 前端 java
坐标地址:com.vladsch.flexmarkflexmark-all0.60.0工具类代码:importcom.vladsch.flexmark.ext.tables.TablesExtension;importcom.vladsch.flexmark.ext.toc.TocExtension;importcom.vladsch.flexmark.html.HtmlRenderer;impo
如何在Java中设计大规模稀疏数据处理架构
省赚客app开发者
java 架构 开发语言
如何在Java中设计大规模稀疏数据处理架构大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在大数据时代,稀疏数据在各个领域变得越来越常见,例如推荐系统、自然语言处理、图像处理等。稀疏数据通常包含大量零值或空值,直接使用传统的数据处理架构可能导致效率低下,内存和计算资源浪费。因此,设计一个高效的稀疏数据处理架构成为Java开发者面临的关键挑战。本文将探讨如何在Java中
leaflet手绘地图实现原理-可视化工具设计手绘地图
diygwcom
leaflet 手绘地图 自定义地图瓦片
在Leaflet中实现手绘地图并添加自定义标注是一个有趣且实用的功能。Leaflet是一个开源的JavaScript库,用于在网页上创建交互式地图。下面是一个基本的实现步骤,包括如何加载手绘地图和添加自定义标注。步骤1:设置HTML页面首先,创建一个基本的HTML页面,并引入Leaflet库。Leaflet手绘地图与自定义标注#map{height:100vh;}//JavaScript代码将在这
量子计算机可以破解比特币吗
weixin_49526058
量子计算 区块链 智能合约 信任链 去中心化 分布式账本 web3
量子计算机可能会对当前的加密算法(包括比特币使用的椭圆曲线加密)带来极大的挑战,尤其是因为它能够使用Shor算法高效地解决离散对数问题。然而,具体到量子计算机破解比特币私钥的情况,需要从以下几个方面深入理解:1.Shor算法与离散对数问题Shor算法是由数学家彼得·肖(PeterShor)在1994年提出的一种量子算法,它可以在多项式时间内解决两类经典计算机难以处理的问题:整数分解问题:这涉及RS
什么是3D视觉无序抓取?
视觉人机器视觉
机器视觉3D 3d 人工智能 视觉检测 计算机视觉 c#
3D视觉无序抓取是一种结合三维视觉技术、机器人控制与智能算法的工业自动化解决方案,旨在实现机器人对散乱、无序堆放的物体进行自主识别、定位和抓取的操作。其核心是通过3D视觉系统获取物体的三维空间信息,结合路径规划与避障算法,引导机械臂完成高精度抓取任务,无需依赖预先设定的固定程序或工装夹具。以下是其关键要点:核心组成与技术原理三维视觉感知:采用3D相机(如结构光、双目视觉、ToF技术)扫描物体表面,
Java中代码的执行顺序(Java基础)
Java搬码工
javaSE java
在Java里,不同类型代码有着特定的执行顺序,理解这些顺序对掌握程序运行逻辑十分关键。下面将详细阐述Java中不同类型代码(静态代码块、实例代码块、构造方法、静态变量、实例变量、静态方法、实例方法等)的执行顺序。单类中的代码执行顺序当只有一个类时,代码执行顺序通常为:静态变量初始化、静态代码块、实例变量初始化、实例代码块、构造方法。classSingleClassExample{//静态变量sta
html
周华华
html
js
1,数组的排列
var arr=[1,4,234,43,52,];
for(var x=0;x<arr.length;x++){
for(var y=x-1;y<arr.length;y++){
if(arr[x]<arr[y]){
&
【Struts2 四】Struts2拦截器
bit1129
struts2拦截器
Struts2框架是基于拦截器实现的,可以对某个Action进行拦截,然后某些逻辑处理,拦截器相当于AOP里面的环绕通知,即在Action方法的执行之前和之后根据需要添加相应的逻辑。事实上,即使struts.xml没有任何关于拦截器的配置,Struts2也会为我们添加一组默认的拦截器,最常见的是,请求参数自动绑定到Action对应的字段上。
Struts2中自定义拦截器的步骤是:
make:cc 命令未找到解决方法
daizj
linux 命令未知 make cc
安装rz sz程序时,报下面错误:
[root@slave2 src]# make posix
cc -O -DPOSIX -DMD=2 rz.c -o rz
make: cc:命令未找到
make: *** [posix] 错误 127
系统:centos 6.6
环境:虚拟机
错误原因:系统未安装gcc,这个是由于在安
Oracle之Job应用
周凡杨
oracle job
最近写服务,服务上线后,需要写一个定时执行的SQL脚本,清理并更新数据库表里的数据,应用到了Oracle 的 Job的相关知识。在此总结一下。
一:查看相关job信息
1、相关视图
dba_jobs
all_jobs
user_jobs
dba_jobs_running 包含正在运行
多线程机制
朱辉辉33
多线程
转至http://blog.csdn.net/lj70024/archive/2010/04/06/5455790.aspx
程序、进程和线程:
程序是一段静态的代码,它是应用程序执行的蓝本。进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。线程是比进程更小的单位,一个进程执行过程中可以产生多个线程,每个线程有自身的
web报表工具FineReport使用中遇到的常见报错及解决办法(一)
老A不折腾
web报表 finereport java报表 报表工具
FineReport使用中遇到的常见报错及解决办法(一)
这里写点抛砖引玉,希望大家能把自己整理的问题及解决方法晾出来,Mark一下,利人利己。
出现问题先搜一下文档上有没有,再看看度娘有没有,再看看论坛有没有。有报错要看日志。下面简单罗列下常见的问题,大多文档上都有提到的。
1、address pool is full:
含义:地址池满,连接数超过并发数上
mysql rpm安装后没有my.cnf
林鹤霄
没有my.cnf
Linux下用rpm包安装的MySQL是不会安装/etc/my.cnf文件的,
至于为什么没有这个文件而MySQL却也能正常启动和作用,在这儿有两个说法,
第一种说法,my.cnf只是MySQL启动时的一个参数文件,可以没有它,这时MySQL会用内置的默认参数启动,
第二种说法,MySQL在启动时自动使用/usr/share/mysql目录下的my-medium.cnf文件,这种说法仅限于r
Kindle Fire HDX root并安装谷歌服务框架之后仍无法登陆谷歌账号的问题
aigo
root
原文:http://kindlefireforkid.com/how-to-setup-a-google-account-on-amazon-fire-tablet/
Step 4: Run ADB command from your PC
On the PC, you need install Amazon Fire ADB driver and instal
javascript 中var提升的典型实例
alxw4616
JavaScript
// 刚刚在书上看到的一个小问题,很有意思.大家一起思考下吧
myname = 'global';
var fn = function () {
console.log(myname); // undefined
var myname = 'local';
console.log(myname); // local
};
fn()
// 上述代码实际上等同于以下代码
m
定时器和获取时间的使用
百合不是茶
时间的转换 定时器
定时器:定时创建任务在游戏设计的时候用的比较多
Timer();定时器
TImerTask();Timer的子类 由 Timer 安排为一次执行或重复执行的任务。
定时器类Timer在java.util包中。使用时,先实例化,然后使用实例的schedule(TimerTask task, long delay)方法,设定
JDK1.5 Queue
bijian1013
java thread java多线程 Queue
JDK1.5 Queue
LinkedList:
LinkedList不是同步的。如果多个线程同时访问列表,而其中至少一个线程从结构上修改了该列表,则它必须 保持外部同步。(结构修改指添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方
http认证原理和https
bijian1013
http https
一.基础介绍
在URL前加https://前缀表明是用SSL加密的。 你的电脑与服务器之间收发的信息传输将更加安全。
Web服务器启用SSL需要获得一个服务器证书并将该证书与要使用SSL的服务器绑定。
http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后
【Java范型五】范型继承
bit1129
java
定义如下一个抽象的范型类,其中定义了两个范型参数,T1,T2
package com.tom.lang.generics;
public abstract class SuperGenerics<T1, T2> {
private T1 t1;
private T2 t2;
public abstract void doIt(T
【Nginx六】nginx.conf常用指令(Directive)
bit1129
Directive
1. worker_processes 8;
表示Nginx将启动8个工作者进程,通过ps -ef|grep nginx,会发现有8个Nginx Worker Process在运行
nobody 53879 118449 0 Apr22 ? 00:26:15 nginx: worker process
lua 遍历Header头部
ronin47
lua header 遍历
local headers = ngx.req.get_headers()
ngx.say("headers begin", "<br/>")
ngx.say("Host : ", he
java-32.通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小(两数组的差最小)。
bylijinnan
java
import java.util.Arrays;
public class MinSumASumB {
/**
* Q32.有两个序列a,b,大小都为n,序列元素的值任意整数,无序.
*
* 要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
* 例如:
* int[] a = {100,99,98,1,2,3
redis
开窍的石头
redis
在redis的redis.conf配置文件中找到# requirepass foobared
把它替换成requirepass 12356789 后边的12356789就是你的密码
打开redis客户端输入config get requirepass
返回
redis 127.0.0.1:6379> config get requirepass
1) "require
[JAVA图像与图形]现有的GPU架构支持JAVA语言吗?
comsci
java语言
无论是opengl还是cuda,都是建立在C语言体系架构基础上的,在未来,图像图形处理业务快速发展,相关领域市场不断扩大的情况下,我们JAVA语言系统怎么从这么庞大,且还在不断扩大的市场上分到一块蛋糕,是值得每个JAVAER认真思考和行动的事情
安装ubuntu14.04登录后花屏了怎么办
cuiyadll
ubuntu
这个情况,一般属于显卡驱动问题。
可以先尝试安装显卡的官方闭源驱动。
按键盘三个键:CTRL + ALT + F1
进入终端,输入用户名和密码登录终端:
安装amd的显卡驱动
sudo
apt-get
install
fglrx
安装nvidia显卡驱动
sudo
ap
SSL 与 数字证书 的基本概念和工作原理
darrenzhu
加密 ssl 证书 密钥 签名
SSL 与 数字证书 的基本概念和工作原理
http://www.linuxde.net/2012/03/8301.html
SSL握手协议的目的是或最终结果是让客户端和服务器拥有一个共同的密钥,握手协议本身是基于非对称加密机制的,之后就使用共同的密钥基于对称加密机制进行信息交换。
http://www.ibm.com/developerworks/cn/webspher
Ubuntu设置ip的步骤
dcj3sjt126com
ubuntu
在单位的一台机器完全装了Ubuntu Server,但回家只能在XP上VM一个,装的时候网卡是DHCP的,用ifconfig查了一下ip是192.168.92.128,可以ping通。
转载不是错:
Ubuntu命令行修改网络配置方法
/etc/network/interfaces打开后里面可设置DHCP或手动设置静态ip。前面auto eth0,让网卡开机自动挂载.
1. 以D
php包管理工具推荐
dcj3sjt126com
PHP Composer
http://www.phpcomposer.com/
Composer是 PHP 用来管理依赖(dependency)关系的工具。你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer 会帮你安装这些依赖的库文件。
中文文档
入门指南
下载
安装包列表
Composer 中国镜像
Gson使用四(TypeAdapter)
eksliang
json gson Gson自定义转换器 gsonTypeAdapter
转载请出自出处:http://eksliang.iteye.com/blog/2175595 一.概述
Gson的TypeAapter可以理解成自定义序列化和返序列化 二、应用场景举例
例如我们通常去注册时(那些外国网站),会让我们输入firstName,lastName,但是转到我们都
JQM控件之Navbar和Tabs
gundumw100
html xml css
在JQM中使用导航栏Navbar是简单的。
只需要将data-role="navbar"赋给div即可:
<div data-role="navbar">
<ul>
<li><a href="#" class="ui-btn-active&qu
利用归并排序算法对大文件进行排序
iwindyforest
java 归并排序 大文件 分治法 Merge sort
归并排序算法介绍,请参照Wikipeida
zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F
基本思想:
大文件分割成行数相等的两个子文件,递归(归并排序)两个子文件,直到递归到分割成的子文件低于限制行数
低于限制行数的子文件直接排序
两个排序好的子文件归并到父文件
直到最后所有排序好的父文件归并到输入
iOS UIWebView URL拦截
啸笑天
UIWebView
本文译者:candeladiao,原文:URL filtering for UIWebView on the iPhone说明:译者在做app开发时,因为页面的javascript文件比较大导致加载速度很慢,所以想把javascript文件打包在app里,当UIWebView需要加载该脚本时就从app本地读取,但UIWebView并不支持加载本地资源。最后从下文中找到了解决方法,第一次翻译,难免有
索引的碎片整理SQL语句
macroli
sql
SET NOCOUNT ON
DECLARE @tablename VARCHAR (128)
DECLARE @execstr VARCHAR (255)
DECLARE @objectid INT
DECLARE @indexid INT
DECLARE @frag DECIMAL
DECLARE @maxfrag DECIMAL
--设置最大允许的碎片数量,超过则对索引进行碎片
Angularjs同步操作http请求with $promise
qiaolevip
每天进步一点点 学习永无止境 AngularJS 纵观千象
// Define a factory
app.factory('profilePromise', ['$q', 'AccountService', function($q, AccountService) {
var deferred = $q.defer();
AccountService.getProfile().then(function(res) {
hibernate联合查询问题
sxj19881213
sql Hibernate HQL 联合查询
最近在用hibernate做项目,遇到了联合查询的问题,以及联合查询中的N+1问题。
针对无外键关联的联合查询,我做了HQL和SQL的实验,希望能帮助到大家。(我使用的版本是hibernate3.3.2)
1 几个常识:
(1)hql中的几种join查询,只有在外键关联、并且作了相应配置时才能使用。
(2)hql的默认查询策略,在进行联合查询时,会产
struts2.xml
wuai
struts
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache