JVM知识总结

2023-11-08

第一章:书籍推荐与JVM相关面试题

1、面试题

https://blog.csdn.net/Y0Q2T57s/article/details/80682013#commentBox

https://blog.csdn.net/Javazhoumou/article/details/98954196

2、书籍推荐

https://detail.tmall.com/item.htm?spm=a230r.1.14.6.2dbd1b4e8hduBh&id=18622814595&cm_id=140105335569ed55e27b&abbucket=13

3、三种JVM

Sun公司的HotSpot

BEA公司的JRockit

https://baike.baidu.com/item/JRockit/5079300

IBM公司的J9 VM

http://book.51cto.com/art/201306/399155.htm

第二章:JVM虚拟机架构

img

第三章:JVM概念

3.1 类加载器

img

img

  1. 从文件系统或者网络加载class信息,把该class信息存放在一块称之为方法区的内存空间

  2. 双亲委派机制:出问题不要找我,找我的“上司”, 一层一层往上找

双亲委派机制有4种类加载器为:

自定义(UserClassLoader)->应用/系统(App/SystemClassLoader)->扩展类(ExtClassLoader)->启动(BootstrapClassLoader)类加载器。

加载过程简述:

​ 当一个类被编译成.class字节码文件进入到jvm的类加载器加载,类加载器首先默认按照顺序:自定义类加载器-->应用程序加载器-->拓展类加载器-->启动类加载器.class直接一层一层往上传递委托给最上层的启动类加载器进行加载,如果启动类能加载这个类,那么他就会进行加载,如果不能,则传递委托给拓展类加载器进行加载;拓展类能加载这个类,那么他就会进行加载,如果不能,则传递委托给应用类加载器进行加载…这样一层一层传递委托下来,自定义类加载器是最后一层类加载器

img

img

public class Test00 {
	public static void main(String[] args) {
		Object object = new Object();
		Test00 test00 = new Test00();
		//System.out.println(object.getClass().getClassLoader());
		System.out.println(test00.getClass().getClassLoader().getParent().getParent());
		System.out.println(test00.getClass().getClassLoader().getParent());
		System.out.println(test00.getClass().getClassLoader());
	}
}
//如果打印结果为null,则表示是启动类加载器
  1. 沙箱安全机制: 保护程序安全 保护JAVA原生的JDK代码

双亲委派优点?

a.安全,可避免用户自己编写的类动态替换Java的核心类,如java.lang.String

b.避免全限定命名的类重复加载(使用了findLoadClass()判断当前类是否已加载)

问题:可不可以自己写个String类(也是自定义的String为何没加载到?)

​ 不可以。因为在类加载中,会根据双亲委派机制去寻找当前java.lang.String是否已被加载。由于启动类加载器已在启动时候加载了该类,所以不会再次加载,因此使用的String是已在java核心类库加载过的String,而不是新定义的String。

3.2 执行引擎

​ 负责解释JVM内部命令,翻译给操作系统执行

3.3 本地方法接口

Java开发中会碰到声明为 native的方法,如:public native int hashCode;这是一个native方法。

为什么存在native方法呢?

native是与C++联合开发的时候用的!使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL( Dynamic Link Library ),由java去调用。

Java不是完美的,Java的不足除了体现在运行速度上要比传统的c/C++慢许多之外,Java无法直接访问到操作系统底层(如系统硬件等),为此Java使用native方法来扩展Java程序的功能

img

3.4 本地方法栈

内存中的一块区域负责登记 native方法

​ 本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而==本地方法栈则是为虚拟机使用到的Native方法服务。==虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(譬如Sun HotSpot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。

3.5 PC寄存器(程序计数器)

是线程私有的,就是一个指针,指向方法区中的方法字节码,指向下一个方法所在的地址,灰色的这几个(Java栈、本地方法栈、程序计数器)都不会被垃圾回收器回收,因为生命周期短

3.6 方法区

(1)方法区(Method Area)与 Java 堆一样,是所有线程共享的内存区域。

(2)静态变量(类变量)、常量、类信息(class/构造方法/接口定义)、运行时常量池存在方法区中

(3)类加载器加载的类信息就放到方法区,该区归所有线程共享
(4)实例变量存在堆内存中,和方法区无关

3.7 Java栈

栈也叫栈内存,在线程创建时创建,生命周期跟随线程生命周期,对于栈来说不存在垃圾回收问题,只要线程一结束该栈就Over,是线程私有的。

8种基本类型的变量、对象的引用变量、实例方法 都是在函数的栈内存中分配。

栈存储什么?

栈帧中主要保存3 类数据:

本地变量(Local Variables):输入参数和输出参数以及方法内的变量;

栈操作(Operand Stack):记录出栈、入栈的操作;

栈帧数据(Frame Data):包括类文件、方法等等

3.8 栈+堆+方法区的交互关系

img

img

第四章:堆

4.1 Heap堆

堆 内存逻辑上分为三部分: 新生代 、老年代、 永久区(Java7以前)

新生区是类的诞生、成长、消亡的区域,一个类在这里产生,应用,最后被垃圾回收器收集,结束生命。

新生区又分为两部分: 伊甸区(Eden space)和幸存者区(Survivor pace),所有的类都是在伊甸区被new出来的。幸存区有两个: 0区(Survivor 0 space)和1区(Survivor 1 space)。

​ 当伊甸园的空间用完时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象实例进行销毁。然后将伊甸园中的剩余对象移动到幸存 0区。若幸存 0区也满了,再对该区进行垃圾回收,然后移动到1区。那如果1区也满了呢?再次垃圾回收,满足一定条件后(年龄增长)再移动到养老区。若养老区也满了,那么这个时候将产生MajorGC(FullGC),进行养老区的内存清理。若养老区执行了Full GC之后发现依然无法进行对象的保存,就会产生OOM异常“OutOfMemoryError”

java.lang.OutOfMemoryError: Java heap space

img

​ 新生代(新生区)+老年代(养老区)+永久代(Java1.7以前)

img

4.2 永久区(方法区)

​ 永久存储区是一个常驻内存区域,用于存放JDK自身所携带的ClassInterface的元数据(也就是核心类库的类和接口),也就是说它存储的是运行环境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭 JVM 才会释放此区域所占用的内存。

Jdk1.6及之前: 有永久代,常量池在方法区

Jdk1.7: 有永久代,但已经逐步“去永久代”,常量池在堆

Jdk1.8及之后: 无永久代,常量池在元空间

因为开发JDK那帮人已经变了,有他们自己到理念

第五章:通过程序理解JVM

5.1 堆分配参数

初始堆大小和最大堆大小可以设置为一样,可以减少GC回收次数 提升性能

img

5.2 堆分配参数

-XX:NewRatio设置新生代和老年代的比例

-XX:SurvivorRatio 设置eden:from:to的比例

img

5.3 堆溢出处理

Java内存分析工具 https://blog.csdn.net/hpc19950723/article/details/53561659

OutOfMemoryError: Java heap space

idea工具https://blog.csdn.net/wytocsdn/article/details/79258247

img

img

img

5.4 Mat的使用

Shallow heap & Retained heap的区别

https://www.iteye.com/blog/bjyzxxds-1532937

Mat工具详细介绍https://blog.csdn.net/liao0801_123/article/details/82900874

img

img

img

img

5.5 栈配置

StackOverflowError栈溢出

img

public class Test04 {
	//-Xss1m  
	//-Xss5m
	//栈调用深度
	private static int count;
	//32977 默认
	//23580 1m
	//214449 5m
	public static void recursion(){
		count++;
		recursion();
	}
	public static void main(String[] args){
		try {
			recursion();
		} catch (Throwable t) {
			System.out.println("调用最大深入:" + count);
			t.printStackTrace();
		}
	}
}

5.6 对象创建在eden区

public class Test05 {
	public static void main(String[] args) {
		//初始的对象在eden区
		//例子一 参数:-Xmx64M -Xms64M -XX:+PrintGCDetails
//		for(int i=0; i< 5; i++){
//			byte[] b = new byte[1024*1024];
//		}	
		
		//测试进入老年代的对象
		//参数:-Xmx1024M -Xms1024M -XX:+UseSerialGC -XX:MaxTenuringThreshold=15 -XX:+PrintGCDetails 
		//-XX:+PrintHeapAtGC
//		for(int k = 0; k<20; k++) {
//			for(int j = 0; j<300; j++){
//				byte[] b = new byte[1024*1024];
//			}
//		}
		
		//1024*1000<1024*1024
		//参数:-Xmx30M -Xms30M -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1024000
		Map<Integer, byte[]> map=new HashMap<>();
		for (int i = 0; i < 5; i++) {
			byte[] b=new byte[1024*1024];
			map.put(i, b);
		}
	}
}

5.7 方法区

方法区溢出 OutOfMemoryError:PermGen space

img

img

5.8 JVM详细配置

http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html

第六章:垃圾回收算法

6.1 可达性分析

img

从GC Roots的对象作为起始点,从这些节点出发所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连的时候说明对象不可用,很显然object5相关的引用已经没用了。

6.2 引用计数算法

img

如果不下小心直接把 Obj1-reference 和 Obj2-reference 置 null。则在 Java 堆当中的两块内存依然保持着互相引用无法回收。无法解决循环引用的情况

6.3 标记清除算法

原理:

当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整个程序(也被 称为stop the world),然后进行两项工作,第一项则是标记,第二项则是清除。

标记:

从引用根节点开始标记所有被引用的对象。标记的过程其实就是遍历所有的GC Roots, 然后将所有GC Roots可达的对象标记为存活的对象。

清除:

遍历整个堆,把未标记的对象清除。

缺点:

此算法需要暂停整个应用,会产生内存碎片

6.4 标记压缩算法(老年代)

用于老年代进行垃圾回收

img

6.5 复制算法(新生代)

用于新生代进行垃圾回收

原理:

对象产生(new)的时候在eden区,当eden空间用完时,程序又需要创建对象,这个时候触发JVM垃圾回收,不再被其他对象所引用的对象就会被销毁,然后将存活对象移动到from,下次再触发垃圾回收的时候eden+from作为主战场,存活对象移动到to区(这个时候to变为from) ,原先form变为to(谁空谁为to);

从from到to的过程每次复制一次对象年龄增长一岁,当年龄达到一定年龄(默认15岁)就会移动到养老区;

若养老区也满了,那么这个时候将产生MajorGC(FullGC),进行养老区的内存清理。若养老区执行了Full GC之后发现依然无法进行对象的保存,就会产生OOM异常“OutOfMemoryError”

交换:

经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。谁空谁为to,

img

因为Eden区对象一般存活率较低,一般的,使用两块10%的内存作为空闲(to)和活动区(from)间,而另外80%的内存(Eden),则是用来给新建对象分配内存的。一旦发生GC,将10%的from活动区间与另外80%中存活的eden对象转移到10%的to空闲区间,接下来,将之前90%的内存全部释放,以此类推。

缺点 :

1、它浪费了一半的内存,这太要命了。

2、如果对象的存活率很高,我们可以极端一点,假设是100%存活,那么我们需要将所有对象都复制一遍,并将所有引用地址重置一遍。复制这一工作所花费的时间,在对象存活率达到一定程度时,将会变的不可忽视。 所以从以上描述不难看出,复制算法要想使用,最起码对象的存活率要非常低才行,而且最重要的是,我们必须要克服50%内存的浪费。

老年代和新生代是否可以交换回收算法?

老年代GC的时候 存活对象较多 如果采用复制算法 效率不高

6.6 分代/分区算法

分代/分区算法也就是新生代和老年代算法的综述(标记压缩算法+复制算法)

第七章:垃圾回收器

垃圾回收收集算法是内存回收的理论,而垃圾回收器是内存回收的实践。

7.1 并行和并发的区别

https://www.cnblogs.com/xc-chejj/p/10813692.html

并发(Concurrent):

在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行。

并发不是真正意义上的“同时进行”,只是CPU把一个时间段划分成几个时间片段(时间区间),然后在这几个时间区间之间来回切换,由于CPU处理的速度非常快,只要时间间隔处理得当,即可让用户感觉是多个应用程序同时在进行。如:打游戏和听音乐两件事情在同一个时间段内都是在同一台电脑上完成了从开始到结束的动作。那么,就可以说听音乐和打游戏是并发的

img

并行(Parallel):

当系统有一个以上CPU(或CPU多核)时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)

其实决定并行的因素不是CPU的数量,而是CPU的核心数量,比如一个CPU多个核也可以并行

img

总结:

所以并发是在一段时间内宏观上多个程序同时运行,并行是在某一时刻,真正有多个程序在运行。

并行和并发的区别:

并发,指的是多个事情,在同一时间段内同时发生了

并行,指的是多个事情,在同一时间点上同时发生了

并发的多个任务之间是互相抢占资源的。

并行的多个任务之间是不互相抢占资源的

只有在多CPU或者一个CPU多核的情况中,才会发生并行。

否则,看似同时发生的事情,其实都是并发执行的

7.2 Serial收集器

Serial是单线程执行垃圾回收的。当需要执行垃圾回收时,程序会暂停一切手上的工作,然后单线程执行垃圾回收。(用于新生代的垃圾回收)

因为新生代的特点是对象存活率低,所以收集算法用的是复制算法,把新生代存活对象复制到老年代,复制的内容不多,性能较好。

img

7.3 ParNew收集器

ParNew同样用于新生代,是Serial的 多线程版本,并且在 参数 、算法(同样是复制算法)上也完全和Serial相同。

Par是Parallel的缩写,但它的并行仅仅指的是收集多线程并行,并不是收集和原程序可以并行进行。ParNew也是需要暂停程序一切的工作,然后多线程执行垃圾回收。

img

因为是多线程执行,所以在多CPU下,ParNew效果通常会比Serial好。但如果是单CPU则会因为线程的切换,性能反而更差

7.4 Parallel Scavenge收集器

新生代的收集器,同样用的是复制算法,也是并行多线程收集。与ParNew最大的不同,它关注的是垃圾回收的吞吐量。

这里的吞吐量指的是 总时间与垃圾回收时间的比例。这个比例越高,证明垃圾回收占整个程序运行的比例越小。

7.5 Serial Old收集器

老年代的收集器,与Serial一样是单线程,不同的是算法用的是标记压缩(Mark-Compact)

img

因为老年代里面对象的存活率高,如果依旧是用复制算法,需要复制的内容较多,性能较差。并且在极端情况下,当存活为100%时,没有办法用复制算法。所以需要用标记压缩Mark-Compact,以有效地避免这些问题

7.6 Parallel Old收集器

老年代的收集器,是Parallel Scavenge老年代的版本。其中的算法替换成Mark-Compact

img

7.7 CMS收集器

CMS(Concurrent Mark Sweep)同样是老年代的收集器。它关注的是垃圾回收最短的停顿时间(低停顿),在老年代并不频繁GC的场景下,是比较适用的。命名中用的是concurrent,而不是parallel,说明这个收集器是有与工作执行并发的能力的。MS则说明算法用的是Mark Sweep算法,来看看具体地工作原理,CMS整个过程比之前的收集器要复杂,整个过程分为四步:

初始标记(initial mark)

单线程执行,需要“Stop The World”,但仅仅把GC Roots的直接关联可达的对象给标记一下,由于直接关联对象比较小,所以这里的速度非常快。

并发标记(concurrent mark)

对于初始标记过程所标记的初始标记对象,进行并发追踪标记,此时其他线程仍可以继续工作。此处时间较长,但不停顿。

重新标记(remark)

在并发标记的过程中,由于可能还会产生新的垃圾,所以此时需要重新标记新产生的垃圾。此处执行并行标记,与用户线程不并发,所以依然是“Stop The World”,时间比 初始时间要长一点。

并发清除(concurrent sweep)

并发清除之前所标记的垃圾。其他用户线程仍可以工作,不需要停顿。

img

由于最耗费时间的并发标记与并发清除阶段都不需要暂停工作,所以整体的回收是低停顿的

缺点:

Mark Sweep算法会导致内存碎片比较多

CMS的并发能力依赖于CPU资源,所以在CPU数少和CPU资源紧张的情况下,性能较差;并发清除阶段,用户线程依然在运行,所以依然会产生新的垃圾,此阶段的垃圾并不会在本次GC中回收,而放到下次。所以GC不能等待内存耗尽的时候才进行GC,这样的话会导致并发清除的时候,用户线程可以利用的空间不足。所以这里会浪费一些内存空间给用户线程预留。

有人会觉得既然Mark Sweep会造成内存碎片,那么为什么不把算法换成Mark Compact呢?

答案其实很简答,因为当并发清除的时候,用Compact整理内存的话,原来的用户线程使用的内存还怎么用呢?要保证用户线程能继续执行,前提的它运行的资源不受影响嘛。Mark Compact更适合“Stop the World”这种场景下使用

7.8 G1收集器

G1,GarbageFirst,在JDK1.7版本正式启用,是当时最前沿的垃圾收集器。G1可以说是CMS的终极改进版,解决了CMS内存碎片、更多的内存空间登问题。虽然流程与CMS比较相似,但底层的原理已是完全不同。高效益优先。G1会预测垃圾回收的停顿时间,原理是计算老年代对象的效益率,优先回收最大效益的对象。

堆内存结构的不同。以前的收集器分代是划分新生代、老年代、持久代等。

7.9 ZGC收集器

在JDK11当中,加入了实验性质的ZGC。它的回收耗时平均不到2毫秒 它是一款低停顿 高并发 的收集器。ZGC几乎在所有地方并发执行的,除了初始标记的是STW的。所以停顿时间几乎就耗费在初始标记上,这部分的实际是非常少的。那么其他阶段是怎么做到可以并发执行的呢?ZGC主要新增了两项技术,一个是着色指针Colored Pointer ,另一个是 读屏障Load Barrier 。

着色指针Colored Pointer

ZGC利用指针的64位中的几位表示Finalizable、Remapped、Marked1、Marked0(ZGC仅支持64位平台),以标记该指向内存的存储状态。相当于在对象的指针上标注了对象的信息。注意,这里的指针相当于Java术语当中的引用。在这个被指向的内存发生变化的时候(内存在Compact被移动时),颜色就会发生变。

在G1的时候就说到过,Compact阶段是需要STW,否则会影响用户线程执行。那么怎么解决这个问题呢?

读屏障Load Barrier由于着色指针的存在,在程序运行时访问对象的时候,可以轻易知道对象在内存的存储状态(通过指针访问对象),若请求读的内存在被着色了。那么则会触发读屏障。读屏障会更新指针再返回结果,此过程有一定的耗费,从而达到与用户线程并发的效果。

把这两项技术联合下理解,与标记对象的传统算法相比,ZGC在指针上做标记,在访问指针时加入Load Barrier(读屏障),比如当对象正被GC移动,指针上的颜色就会不对,这个屏障就会先把指针更新为有效地址再返回,也就是,永远只有单个对象读取时有概率被减速,而不存在为了保持应用与GC一致而粗暴整体的Stop The World。

ZGC虽然目前还在JDK 11还在实验阶段,但由于算法与思想是一个非常大的提升,相信在未来不久会成为主流的GC收集器使用

7.10 AliGC收集器

https://yq.aliyun.com/articles/277268

AliGC是阿里巴巴JVM团队基于G1算法, 面向大堆(LargeHeap)应用场景

指定场景下的对比

img

img

7.11 垃圾回收器分类图解

img

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM知识总结 的相关文章

  • Android:java.lang.OutOfMemoryError:

    我在 Android 上开发了一个使用大量图像的应用程序 可绘制文件夹中有很多图像 比如说超过 100 张 我正在开发图像动画应用程序 我使用 imageview 来显示 GIF 图像 我使用了将 gif 图像分割成多个 PNG 格式图像的
  • Selenium:将 Internet Explorer 中的文件下载到指定文件夹,无需直接链接,无需 Windows 窗体,无需 AutoIt 或 Robot

    我经常遇到一个问题 如何在 IE 中下载文件 与 Firefox 的 Chrome 不同 您不能只指定所需的文件夹 所有文件都会下载到该文件夹 您还需要与本机 Windows 表单等进行交互 有多种选项 例如使用 AutoIt 使用键盘命令
  • 如何在ArrayList中的特定位置插入对象

    假设我有一个大小为 n 的对象的 ArrayList 现在我想在特定位置插入另一个对象 假设在索引位置 k 大于 0 且小于 n 并且我希望索引位置 k 处及其之后的其他对象向前移动一个索引位置 那么有没有什么方法可以直接在Java中做到这
  • 如何在 Android 中的 Chrome 或 Firefox 等特定浏览器的 Web 视图中加载应用程序

    我是 Android 新手 我正在做一个应用程序 我需要在平板电脑上的 Web 视图中加载现有的应用程序 在平板电脑中 当我使用 Web 视图加载应用程序时 我的应用程序将加载到默认浏览器中 如何在平板电脑上的 Web 视图中的特定浏览器
  • java 中的梵文 i18n

    我正在尝试使用来自互联网的示例 ttf 文件在 java 中使用 i18n 进行梵文 印地文 我可以加载资源包条目 还可以加载 ttf 并设置字体 但它不会根据需要呈现 jlabel 它显示块代替字符 如果我在 Eclipse 中调试 我可
  • 垂直 ViewPager 中的动画

    我需要垂直制作这个动画ViewPager https www youtube com watch v wuE 4jjnp3g https www youtube com watch v wuE 4jjnp3g 这是我到目前为止所尝试的 vi
  • 如何准确判断 double 是否为整数? [复制]

    这个问题在这里已经有答案了 具体来说 在 Java 中 我如何确定double是一个整数 为了澄清 我想知道如何确定 double 实际上不包含任何分数或小数 我主要关心的是浮点数的性质 我想到的方法 以及我通过谷歌找到的方法 基本上遵循以
  • Apache Thrift Java-Javascript 通信

    我正在编写一个基于 Apache Thrift 的 Java 服务器 它将从 Javascript 客户端接收数据 我已经完成了 Java 服务器 但问题是我可以获得 Javascript 客户端的工作示例 我无法找到一个好的示例 构建文档
  • 为什么通过 方法向 List 添加元素(类型正确)会出现编译错误? [复制]

    这个问题在这里已经有答案了 我对泛型通配符概念几乎没有疑问 1 假设我有一个方法 void write List
  • 获取Android库中的上下文

    我正在编写一个 Android 应用程序 它的一些功能封装在内部库中 但是 要使此功能发挥作用 库需要一个应用程序上下文的实例 为图书馆提供这种上下文的最佳方式是什么 我看到了一些选择 但没有一个有吸引力 Have my library c
  • Maven WebApp META-INF context.xml

    我正在使用 Maven 3 并且尝试在 webapp 文件夹下添加 META INF 文件夹 所以我正在尝试执行以下操作 src main webapp META INF context xml WEB INF 下面是我的 POM 文件
  • java项目中无法加载类“org.slf4j.impl.StaticLoggerBinder”错误? [复制]

    这个问题在这里已经有答案了 我越来越Failed to load class org slf4j impl StaticLoggerBinder 错误 我想将记录器写入文件 所以我使用了 log4j jar 并使用 apache tomca
  • 对对象集合进行排序[重复]

    这个问题在这里已经有答案了 如果我有一个简单的字符串列表 List
  • 在拇指上方显示修改后的 JSlider 值

    有没有一种简单的方法可以在使用某些 外观和感觉 的同时更改 JSlider 上方标签中显示的值 为了清楚起见 我正在谈论这个值 具体来说 我想显示除以 1000 的值而不是值本身 我知道如果我显示它们 我可以为刻度设置标签 但用户将不得不猜
  • 但是创建静态实用方法不应该被过度使用吗?如何避免呢? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 随着时间的推移 java项目中引入了许多实用方法来完成更复杂和简单的任务 当使用静态方法时 我们在代码中引入了紧密耦合 这使得我们的代
  • Java 中如何验证字符串的格式是否正确

    我目前正在用 Java 编写一个验证方法来检查字符串是否是要更改为日期的几种不同格式之一 我希望它接受的格式如下 MM DD YY M DD YY MM D YY 和 M D YY 我正在测试第一种格式 每次它都告诉我它无效 即使我输入了有
  • 如何在 Eclipse 中获得完全限定的类名?

    有没有一种快速方法可以在 Eclipse 中单击 Java 类并获取其完全限定名称 或将其复制到剪贴板 2016年6月29日编辑 正如 Jeff 所指出的 您只需要执行以下第二步 1 Double click on the class na
  • 是否可以手动检查 LocateRegistry 是否存在?

    I 已经发现 https stackoverflow com a 8338852 897090一种安全的方式获得LocateRegistry 即使注册表尚不存在 Registry registry null try registry Loc
  • Java 8 方法签名不一致

    Java 8 为我们提供了具有很长签名的新方法 如下所示 static
  • Java 中序列化的目的是什么?

    我读过很多关于序列化的文章 以及它如何如此美好和伟大 但没有一个论点足够令人信服 我想知道是否有人能真正告诉我通过序列化一个类我们真正可以实现什么 让我们先定义序列化 然后我们才能讨论它为什么如此有用 序列化只是将现有对象转换为字节数组 该

随机推荐

  • PCL 体素滤波(C++详细过程版)

    体素滤波 一 概述 二 代码实现 三 结果展示 1 原始点云 2 滤波结果 一 概述 体素滤波PCL中经典的点云下采样算法 具体算法原理和实现代码见 PCL体素滤波器 为充分了解算法实现的每一个细节和有待改进的地方 使用C 代码对算法实现过
  • 力扣题---二叉树---相同的树

    题目连接 相同的树 首先我看题目要求以及例题 给你两棵二叉树的根节点 p 和 q 编写一个函数来检验这两棵树是否相同 如果两个树在结构上相同 并且节点具有相同的值 则认为它们是相同的 示例 1 输入 p 1 2 3 q 1 2 3 输出 t
  • FeignClient接口的几种方式总结

    FeignClient这个注解 已经封装了远程调用协议 在springboot的开发 或者微服务的开发过程中 我们需要跨服务调用 或者调用外部的接口 我们都可以使用FeignClient 一 FeignClient介绍 FeignClien
  • ChatGLM2-6B本地部署

    ChatGLM2 6B本地部署 ChatGLM2 6B 是开源中英双语对话模型 ChatGLM 6B 的第二代版本 在保留了初代模型对话流畅 部署门槛较低等众多优秀特性的基础之上 ChatGLM2 6B 引入了如下新特性 更强大的性能 基于
  • uniapp截取部分区域

    通过canvas来绘制截取部分 然后保存 html部分
  • 手把手教你,Selenium 遇见伪元素该如何处理?

    问题发生 在很多前端页面中 大家会见到很多 before after 元素 比如 百度流量研究院 比如 百度疫情大数据平台 以 百度疫情大数据平台 为例 累计确诊 文本并没有显示在 HTML 源代码中 如果通过常规的 xpath 元素定位方
  • Java 经典面试题:聊一聊 JUC 下的 LinkedBlockingQueue

    本文聊一下 JUC 下的 LinkedBlockingQueue 队列 先说说 LinkedBlockingQueue 队列的特点 然后再从源码的角度聊一聊 LinkedBlockingQueue 的主要实现 LinkedBlockingQ
  • c++中的关联容器

    c 中的关联容器主要是map set 已经multimap multiset 为了讲map 得先将pair类型 pair就是一个两个类型的组合 比如一个人的学号就可以是pair
  • 【重磅最新】163篇ICML-2021强化学习领域论文整理汇总(2021.06.07)

    深度强化学习实验室 官网 http www neurondance com 论坛 http deeprl neurondance com 作者 深度强化学习实验室 来源 整理自https icml cc ICML 是机器学习领域最重要的会议
  • 【python爬虫专项(25)】新型冠状病毒肺炎B站视频弹幕数据爬并做数据词云展示

    1 查看要爬取页面 打开B站网址 输入 新型冠状病毒肺炎 关键字 显示界面如下 2 确定爬虫逻辑 查看网页的内容后 一个网址页面下20个视频 这里只采集20页的视频数据 共400个视频 因为是出现的视频按照点击量进行排序的 所以再往后的视频
  • Java使用多线程异步执行批量更新操作

    写在前面 相信不少开发者在遇到项目对数据进行批量操作的时候 都会有不少的烦恼 尤其是针对数据量极大的情况下 效率问题就直接提上了菜板 因此 开多线程来执行批量任务是十分重要的一种批量操作思路 其实这种思路实现起来也十分简单 就拿批量更新的操
  • 观察者模式(Observer)

    一 观察者模式定义 对象间的一种一对多的依赖关系 当一个对象的状态发生改变时 所有依赖它的对象都得到通知并自动更新 二 观察者模式的结构说明 1 Subject 目标对象 a 一个目标可以被多个观察者观察 b 目标可以提供添加和删除观察者
  • Linux usb gadget框架概述

    大大小小开发了四个与gadget相关的驱动 字符驱动 g multi g ether g zero 在这里把自己对gadget的开发中自己的感悟记录之 想要了解gadget 必须了解其框架 知道composite gadget udc三者之
  • Vue+百度统计 实现网页的PV和UV统计

    目录 什么是PV和UV 百度统计 VUE 验证安装 查看统计 拓展 什么是PV和UV 这里我懒得打字了 直接百度扒过来吧 这个了解知道是啥就行 百度统计 首先你要有个百度账号 自己测试的时候可以用自己的百度个人账户 项目里向公司申请企业商业
  • JAVA byte类型转String类型

    问题 RSA加密 byte类型转String类型 格式转换之后内容变了 解密解不出来 第一种方式 使用 ISO 8859 1 编码 使用此方式编码返回结果会乱码 例如 public static void main String args
  • 超详细Shell学习教程第四篇shell脚本参数化

    目录 1 1参数化实例 1 2参数处理说明 1 3带返回值的参数 书写带参数的shell脚本 1 1参数化实例 创建bash1 sh bin bash echo Shell 传递参数实例 echo 第一个参数为 1 echo 参数个数为 e
  • 学习swoole框架需要杀掉9501进程,强制的解决办法

    1 查看进程 我们运行一下命令 netstat anp grep 9501 2 看出进程29698占用的9501端口 3 强制杀死进程 kill 9 29698 强制
  • python自动化(三):selenium微博抢票(含抢票程序设计思路)

    缘起 这个故事起源于女票是一个bjd娃圈爱好者 我才知道在娃圈里经常通过微博私信的方式进行一些商品的交易 例如娃娃的面妆 衣服和娃娃本身 这就引发了抢票需求 流程 在某一个整的时间点进行微信的私信发送 排名靠前者获得 人工操作反应慢 只能提
  • 不卸载重装,直接升级TeX Live的方法(Win11)

    不卸载重装 直接升级TeX Live的方法 Win11 1 前言 前两天想要用LaTeX写中文文档 更新ctex宏包的时候想起来已经好久没有更新TeX Live版本 上网查了下 TeX Live的2022版本已经可以使用 觉得可以在写文档的
  • JVM知识总结

    第一章 书籍推荐与JVM相关面试题 1 面试题 https blog csdn net Y0Q2T57s article details 80682013 commentBox https blog csdn net Javazhoumou