JVM 是一个进程, 一台机器可以运行多个JVM吗?

没问题,当然可以运行多个JVM 。

JVM启动的时候,如果没有进行参数配置,默认的内存占用是怎么样的呢?

启动多个 JVM 的时候,如果内存不足了,最后一个启动的 JVM 会怎么样?

通过参数设置了 JVM 占用的内存大小后,如果内存还是超了,会怎么样呢? 宕机? 进程挂掉?

内存溢出问题?内存溢出会导致整个 JVM 进程挂掉吗?

内存溢出以后,怎么进行修复呢?

JVM 进程挂掉的话,怎么进行内存布局的分析,知道宕机的原因呢?

虚拟机执行引擎是什么东西? 为什么需要这个东西? 这个东西是怎么运行起来的?

JVM 类加载的整个过程是怎么样的?

加载-验证-准备-解析-初始化-使用-卸载

为什么是这样的一个加载过程? 这样设计有什么好处?

开发的时候,可以在这个过程中参与哪一部分? 这种参与的动作,有什么现在已经实现好的比较好的例子吗?

JVM 占用的内存布局是怎么样的? 为什么要这样划分?这样划分有什么好处? 有其它的划分方法吗 ? 其它的虚拟机也是按照这样划分的吗?

java程序中,某个业务流程涉及很多步骤,中间某步骤不符合条件,如何中断整个流程? 是用异常 还是 用返回结果true/false判断来逐层终止


wait和sleep方法的区别

wait是Object类里,sleep是Thread里,wait()需要同步代码块使用,而sleep()不需要,wait(),notify notifyAll 锁是绑定到对象中,而不是绑定到线程中,Sleep不释放锁,wait会释放锁,一个线程状态是wait一个是wait time

NEW 新建状态,线程创建且没有执行start方法时的状态
RUNNABLE 可运行状态,线程已经启动,但是等待相应的资源(比如IO或者时间片切换)才能开始执行
BLOCKED 阻塞状态,当遇到synchronized或者lock且没有取得相应的锁,就会进入这个状态
WAITING 等待状态,当调用Object.wait或者Thread.join()且没有设置时间,在或者LockSupport.park时,都会进入等待状态。
TIMED_WAITING 计时等待,当调用Thread.sleep()或者Object.wait(xx)或者Thread.join(xx)或者LockSupport.parkNanos或者LockSupport.partUntil时,进入该状态
TERMINATED 终止状态,线程中断或者运行结束的状态

image.png

2020-06-22

为什么要从堆内复制到堆外给os,而不是直接从堆内直接给os呢?

在jvm层面看,gc堆就是一个超大的数组,在c语言 里面就是 int gc[size], 这个gc数组就是所谓的java的堆,除开这个数组以外的所有空间就是gc 堆外内存,其实从操作系统的角度来看都是一样的内存,这个数组以外的所有空间就是gc 堆外内存。发起系统调用的时候要传一个指针参数进去,这个地址不能变的,如果一个线程从gc堆内传了一个指针过去,但是这个时候要gc,垃圾回收之后,地址就不一样了。

谈谈你对AQS的理解?

addWaiter和enq方法中新增一个节点为什么先将新节点的prev置为tail,再尝试cas,而不是cas成功之后来构造节点之间的双向链接?

唤醒节点为什么从tail往前遍历?

unparkSuccessor有新线程争锁是否有漏洞?

aqs如何保证队列活跃?

Propagate状态的节点存在的意义?

https://blog.csdn.net/tiankong_12345/article/details/89742670#%E6%8F%92%E5%85%A5%E8%8A%82%E7%82%B9%E6%97%B6%E7%9A%84%E4%BB%A3%E7%A0%81%E9%A1%BA%E5%BA%8F


java synchronized锁对象,但是当对象引用是null的时候,锁的是什么?

会有NPE抛出
https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.19

系统故障,如果没有dump文件,如何查找问题?

操作系统开启ulimit -c 。不等于0会在java进程挂掉阻塞一段时间,留给操作系统保留现场,生成一个core dump,然后通过工具转化成jvm dump

为什么Hotspot JVM 在大对象分配时需要一个连续的内存空间?

简单实现、速度快、性能好。

JVM有哪些部分组成?

  1. JVM主要组成部分:类加载器、运行时数据区、执行引擎、本地库接口<br /> 运行时数据区:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区

怎么样通过Java程序来判断JVM是32位还是64位?

// 通过Java程序来判断: System.out.println(System.clearProperty(“sun.arch.data.model”));
// sun.arch.data.model=32 32bit JVM
// sun.arch.data.model=64 64bit JVM

java的gc为什么要分代?

对传统的GC的实现,在整个GC过程中都要”stop -the -world”,如果能想办法缩短GC一次工作的时间长度就是件重要的事情。如果说收集整个GC堆耗时太长,那不如只收集其中的一部分。
所以可以通过分代思路来解决,分代思路基于:大部分对象的声明周期很短,没有死亡的对象则可能会存活很长时间。所以基于这种情况,如果让新创建的对象都在young gen 里创建,然后频繁收集young gen,则大部分垃圾都能在young GC 中被收集掉。由于young gen 的大小配置通常只占整个GC堆的较小部分,而且较高的对象死亡率(或者说较低的对象存活率)让其非常适合使用copying算法来收集,这样就能降低单次GC的时间长度,还可以提高GC的工作效率。

younggc和fullgc谁对应的gc roots更大?

在young GC中不收集old gen,所以old gen里的对象此时全部都会被认为是活的,那么从这些对象出发指向young gen的引用就必须被认为是活的。因而把这些引用看作root set的一部份。


某台服务频繁fullgc,但是younggc次数相对较少,可能因为哪些原因?

1.经常有超过大对象阈值的对象进入老年代,可以通过-XX:PretenureSizeThreshold设置
2.老年代参数设置不当,-XX:CMSInitiatingOccupancyFaction=92设置不合理,导致频繁FULLGC
3.FULLGC之后没有整理老年代内存碎片,导致没有连续可用的内存地址,进入恶性循环,导致频繁老年代GC,-XX:CMSFullGCsBeforeCompaction可以设置
4.新生代过小,或者e区和s区比例不当,对象通过动态年龄判断机制频繁进入老年代。
5.不合理使用System.gc(),造成频繁的FullGC,-XX:+DisableExplicitGC这个参数可以禁用System.gc().
6.存在内存泄露,老年代中驻扎着大量不可回收的对象,一定程度上缩小了老年代的大小,造成对象一进入老年代就触发FULLGC
7.Meatspace不够用引发fullgc,甚至无限fullgc,这类问题常见于tomcat热部署,以及使用反射不当。

分代收集时,如何解决对象跨代引用所带来的gc roots扫描范围增加的问题?

回答一:
我们就不应再为了少量的跨代引用去扫描整个老年代,也不必浪费空间专门记录每一个对象是否存在及存在哪些跨代引用,只需在新生代上建立一个全局的数据结构(该结构被称为“记忆集”,Remembered Set),这个结构把老年代划分成若干小块,标识出老年代的哪一块内存会存在跨代引用。此后当发生Minor GC时,只有包含了跨代引用的小块内存里的对象才会被加入到GC Roots进行扫描。虽然这种方法需要在对象改变引用关系(如将自己或者某个属性赋值)时维护记录数据的正确性,会增加一些运行时的开销,但比起收集时扫描整个老年代来说仍然是划算的。

回答二:
1.分代收集时,如何解决对象跨代引用所带来的gc roots扫描范围增加的问题?
夸代引用是指 老年代引用新生代。
使用卡表来判断, 卡表记录新生代对象是否被老年代引用。如果卡表索引值为1说明是脏页,表示是引用了,在垃圾回收时,只要筛选出卡表中变张的元素,就能知道哪些卡页对应的内存包含夸代指针,把他们加入GC Roots中一并扫描。

jvm关闭时死循环线程是否会退出?

JVM 一旦退出了,线程自然也会退出的,Java 线程无法独立于 Java 进程存在的。
不过,根据题主贴的代码,我想题主想问的是,当 main thread 结束之后,这个线程会不会停止运行。当 main thread 运行结束之后,JVM 会等待其他 non-daemon thread 运行结束,然后不管 daemon thread 是否还在运行,JVM 直接就退出了。也就是说,如果你这个线程是 non-daemon thread,那么 JVM 不会退出,一直等待你这个线程运行结束,也就是 run() 方法返回,否则 JVM 直接就退出了,你这个线程也就没了,连捕捉 InterruptedException 的机会都没有。默认情况下,一个线程被创建出来是 non-daemon 线程,你可以调用 Thread 类的 setDaemon() 方法将它变成 daemon 线程。
除了上面这种,在以下两种情况下,JVM 不管你是不是 daemon 线程,都不会等待你运行结束,直接停止运行。

  • 收到 signal。
  • 在 Java 代码里调用了 System.exit(int)。

jvm是如何处理异常的?

1、在编译生成的字节码中,每个方法都附带一个异常表。异常表中的每一个条目代表一个异常处理器,并且由from指针、to指针、target指针以及所捕获的异常类型构成。这些指针的值时字节码索引,用以定位字节码。from指针和to指针标示了该异常处理器所监控的范围,target指针则所指向异常处理器的起始位置。
2、当触发异常时,Java虚拟机会从上至下遍历异常表中的所有条目。当触发异常的字节码的索引值在某个异常表条目的监控范围内,Java虚拟机会判断抛出的异常和该条目想要捕获的异常是否匹配。如果匹配,然后将控制流转到该条目target指针指向的字节码。

jvm如何实现反射?

1、反射是调用Method.invoke(),java.lang.reflect.Method#invoke 先进入委派实现(jdk.internal.reflect.DelegatingMethodAccessorImpl#invoke)再进入本地实现(jdk.internal.reflect.NativeMethodAccessorImpl#invoke)
使用委派实现的原因是有当调用本地实现超过默认15(jdk.internal.reflect.ReflectionFactory#inflationThreshold)次之后,Java会生成动态实现GeneratedMethodAccessor。
public Object invoke(Object obj, Object[] args)
throws IllegalArgumentException, InvocationTargetException
{
// 判断超过15次
if (++numInvocations > ReflectionFactory.inflationThreshold()
&& !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
MethodAccessorImpl acc = (MethodAccessorImpl)
new MethodAccessorGenerator().
generateMethod(method.getDeclaringClass(),
method.getName(),
method.getParameterTypes(),
method.getReturnType(),
method.getExceptionTypes(),
method.getModifiers());
parent.setDelegate(acc);
}

return invoke0(method, obj, args);<br />}

2、动态实现和本地实现相比,其运行效率要快上 20 倍,本地实现的优点是初始化快,但是运行次数多了会相对动态实现慢,动态实现初始化慢,执行次数多了之后,性能会相对本地实现更快。

java虚拟机是如何实现synchronized?

g1垃圾收集器的原理?

G1收集器:淡化了分代布局的概念,基于Region的内存布局形式,将堆内存分为多个Region,这些Region既可以充当Edn,Survivor 还可以充当老年代
Region作为一次回收的最小单元,可以避免在整个堆上进行垃圾回收,让G1收集器去跟踪各个Region里面的垃圾堆积的“价值”大小,价值即回收所获得的空间大小
以及回收所需时间的经验值,然后在后台维护一个优先级列表优先处理回收价值收益最大的那些Region,这也就是“Garbage First”名字的由来。这种使用Region划分内存空间,
以及具有优先级的区域回收方式,保证了G1收集器在有限的时间内获取尽可能高的收集效率。

java虚拟机在即时编译语境下,判断对象是否逃逸的依据是什么?

jvm是怎么实现invokedynamic的?

每一处含有invokedynamic指令的位置都被称作“动态调用点”,这条指令的第一个参数是CONSTANT_InvokeDynamic_info常量,从这个常量中可以得到三个信息:引导方法、方法类型和名称。引导方法是固定的参数,并且返回值规定是java. lang. invoke. CallSite对象,这个对象代表了真正要执行的目标方法调用。根据常量中提供的信息,虚拟机可以找到并且执行引导方法,从而获得一个CallSite对象,最终调用到要执行的目标方法上。

Java中的线程在系统进行I/O操作时,线程是什么状态?(B)

A.new
B.runnable
C.blocked
D.wating
E.timed_waiting
F.terminated

jdk1.0大概是在95年,juc包大概在jdk1.5,2008年左右,那么中间这么多年是如何进行线程之间的协同的?

JDK1.8中Executors中新增加的newWorkStealingPool是如何实现的?为什么加入这种?

                            • -
                              用了双端队列,主要目的就是,多个线程可能执行能力不一样,
                              从字面意思看,就是当有些处理的比较快,他就会steal(偷)其他线程的任务,从队列的尾部偷走

                              Java中,如何在一个线程中捕获另一个线程抛出的异常?

                              主捕获子可以用Thread.UncaughtExceptionHandler 全局捕获。或者继承ThreadGroup 会 uncaughtException方法中捕获线程异常。
                              子捕获子:
                              exchange 可以两个线程互换信息。
                              共享内存。

                              Java中,线程调用start方法之后,jvm和操作系统会发生什么?


Java中,为什么lambda表达式中只能访问局部变量是final修饰和effetively final


使用final修饰符真的能提高效率吗?

将一个方法设成final后,编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。只要编译器发现一个final方法调用,就会(根据它自己的判 断)忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。相 反,它会用方法主体内实际代码的一个副本来替换方法调用。这样做可避免方法调用时的系统开销。当然,若方法体积太大,那么程序也会变得雍肿,可能受到到不到嵌入代码所带来的任何性能提升。因为任何提升都被花在方法内部的时间抵消了。
https://www.zhihu.com/question/66083114


Java中,synchronized在哪些场景下会进行锁降级?

就是 synchronized1其实是可以进行锁降级的,方腾飞那个版本的书,可能是jvm的实现没有做这方面实现(不确定),但是java8是有对应实现的
锁降级是发生在gc 过程中的STW 时间,这时候vmThread 会对所有monitor进行遍历,或者就是如我刚才发的代码里,他会对所有依赖monitorInuseLists值的正在 使用Monitor子序列进行遍历。从而获得可以对哪些Monitor对象最为 “降级对象”

从重量级锁-》轻量级锁
将存储在ObjectMonitor对象中的markOop重新set到Object的对象头里

Private修饰的方法可以通过反射访问,那么private的意义是什么?

java中,创建一个对象,这个对象最小是多少字节?最大是多少字节?

参考:32位虚拟机:
4字节MarkWord + (开启指针压缩)4字节(不开启指针压缩)8字节 + (如果是数组)4字节(如果不是数组)0字节 + (实例数据,基础类型按照基础类型大小,如果是引用类型【开启指针压缩4字节】【不开启指针压缩8字节】)+对齐补充(满足8字节的倍数)
64位虚拟机:
8字节MarkWord + (开启指针压缩)4字节(不开启指针压缩)8字节 + (如果是数组)4字节(如果不是数组)0字节 + (实例数据,基础类型按照基础类型大小,如果是引用类型【开启指针压缩4字节】【不开启指针压缩8字节】)+对齐补充(满足8字节的倍数)

32位操作系统进程能使用最大内存为4G

java中,什么样的接口能被定义为函数式接口?lambda表达式和普通代码之间是否有性能差异,差异在哪里?


java中,局部变量使用前需要显式的赋值,否则编译不过,为何如此设计?


java和c语言的执行效率是在哪些方面有差异?python呢?

java中,内部类和匿名内部类编译后都会生成.class文件嘛?生成的class有什么区别

java虚拟机中,什么情况会优化重复的读写操作?

java中是否有不可重入锁?如果有的话,不可重入锁的优点是?


java中,使用线程池无法一次性设置最合适的参数,所以如何动态的修改线程池参数,使得缩短线上故障恢复的时间?

2021-01-20

如何设计一个良好的api?从哪些层面去考虑

2021-01-21

在springframework中,属性的依赖注入和构造器注入的时机一样么?哪种会出现循环依赖?

2021-01-22

在操作系统层面,有哪些优化内存的手段和思路?

2021-01-25

视频会议中的丢包现象有办法解决么?

2021-01-26

jvm中有并行垃圾收集,并发垃圾收集等等模式,为何在java7中还出现了g1垃圾收集算法?

2021-01-29

java的每一个版本中,你觉得哪个版本的更新是有划时代意义的?或者说你觉得最好的?

2021-02-01

应用系统中,如果请求流量特别大,依靠缓存也吃力的时候,你还有哪些手段提高系统可用性和稳定性?

2021-02-22

电商系统中,如何设计订单号服务?
答:考量的点有1.分布式事务 2.订单数据安全 3.日后无痛迁移 4.能够扛住高并发

2021-02-23

Java中,调用对象的wait方法之前,为什要先获取相应的对象锁?类似如下
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
… // Perform action appropriate to condition
}
答:看源码注释

2021-02-24

Java中,如何看待所有类的父类都是object这种设计?
答:一,为了万物皆对象,有一个对象可以管理。第二方便垃圾回收机制,这样所有的对象都会有垃圾回收的方法,而不用每一个对象都进行不同的定义。三 集合类方便,不用为了实现集合重复的实现类别,因为所有的对象都是object的子类,所以对于集合来说只要put和add只要是object类型就可以满足,不用因为不同的集合去实现不同的方法。

2021-02-25

Java中的线程池,核心线程异常中断之后是否会补上?如果会是在什么时机?
非核心线程发生异常之后会如何处理?

2021-02-26

Java程序读取一个大文件,并且同时有其他线程进行并发读写的操作,如何进行存储的设计?如何读取和写入不会有脏数据影响?

2021-03-03

共享内存分为几种,使用共享内存有什么好处,在java中如何使用?

2021-03-04

今日的题目由我们的八股之神5神给大家提供的一道考察类加载相关的经典问题,题目如下
https://www.yuque.com/docs/share/09797247-3d0f-4234-a9a5-0ba407f06540?# 《阐述下代码的执行过程》

2021-03-05

如果让你设计一个延迟队列,你会怎么设计?
使用二叉堆跟时间轮分别实现,两者优缺点是什么?分别适合什么场景

2021-03-06

在业务开发中,在线程池中的线程如何与主线程之间进行传递上下文?如果上下文传递成功了,线程池的队列满了,使用的不同的拒绝策略,会出现哪些不同的情况?

2021-03-07

如果让你设计一个延迟队列,你会怎么设计?
使用二叉堆跟时间轮分别实现,两者优缺点是什么?分别适合什么场景

2021-03-08

在业务开发中,在线程池中的线程如何与主线程之间进行传递上下文?如果上下文传递成功了,线程池的队列满了,使用的不同的拒绝策略,会出现哪些不同的情况?

2021-03-09

如果让你用java设计一款分库分表中间件你会怎么设计?考量哪些点?如何兼容jdbc的规范?

2021-03-10

类加载的过程中,加载,验证,准备,解析,初始化都做了哪些事情?这些顺序先后对调会有什么影响?哪些步骤是强依赖先后顺序的
答:1、遇到new、 getstatic、 putstatic或invokestatic这四条字节码指令时, 如果类型没有进行过初始化,则需要先触发其初始化阶段。 能够生成这四条指令的典型Java代码场景有:

使用new关键字实例化对象的时候。
读取或设置一个类型的静态字段(被final修饰、 已在编译期把结果放入常量池的静态字段除外)的时候。
调用一个类型的静态方法的时候。
2、使用反射的时候,如果类没有进行过初始化,则需要先进行初始化。

3、初始化类的时候,如果其父类还没有进行过初始化,则需要先初始化其父类,但是一个接口在初始化 时, 并不要求其父接口全部都完成了初始化, 只有在真正使用到父接口的时候(如引用接口中定义的常量) 才会初始化。

4、虚拟机启动时,会先初始化主类(main()所在类)。

5、当使用jdk1.7动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getstatic,REF_putstatic,REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先出触发其初始化。

6、在jdk1.8中,如果一个接口中定义了默认方法(default修饰的方法),如果有这个接口的实现类进行了初始化,则需要在该实现类初始化之前先初始化该接口。

2021-03-11

Java线程池为什么core线程满了,来了新任务是丢队列内而不是根据设置的max线程数量创建新的线程?
为什么线程池启动,提交一个任务是创建core线程,不是放队列内,这么设计的好处在哪里?

2021-03-12

设计一个新浪微博某顶流海量评论中抽奖,且保证实时和公平(楼中楼的评论也算在抽奖名额当中)

2021-03-17

使用shardingjdbc进行分库分表,如果查询里面没有带 sharding key,那么会有什么影响?怎么解决这个场景?(可以有多个方案哟)

2021-03-19

mysql中的四种隔离级别的适用场景是什么?

2021-03-22

聊聊TCP是不是一定可靠的?

2021-03-23

如何优雅的中止一个线程?

2021-03-24

系统oom之后应用系统会被杀死么?堆外内存的oom该如何排查

2021-03-25

java中的instanceof的实现原理是如何?(某厂原题)

2021-03-26

关于降低消息延迟的方式,哪种说法是错误的?(A)
A.增加消费者数量,来提升存储在kafka中消息消费性能
B.可以在消费端启动多个线程,来提升消息的消费性能
C.在存储上使用Page Cache异步刷盘,提升写入性能
D.使用零拷贝技术,减少数据拷贝的次数,提升消息队列的性能

2021-03-29

在10wqps下,对rpc接口的性能优化有哪些方式?(排除掉对业务逻辑的优化)

2021-03-30

epoll的模型是什么样的?epoll的惊群效应如何解决?

2021-04-25

1.为什么jvm不保证Class.getmethods方法返回顺序不一致?(相同代码不同机器)2.答案参见effective java第十三节
在设计一个api层面上,为什么建议使类和成员的可访问性最小化?

  1. 为什么wait和notify方法是在 Object 类而不是 Thread 中声明的?

1.jvm中的跨代引用会在哪些场景出现?(比如年轻代的对象引用了老年代的对象,或者老年代的对象引用了年轻代的对象)?

1.计算机申请内存的时候底层发生了什么?

2021-09-01

Class.forName(classname)和ClassLoader.loadClass(classname)两种加载类的方式有什么区别?

2021-09-10

今天出一个有意思的题目,java中如果方法名过长,会影响到程序并发执行的性能么?
会影响到执行的性能,但是和并发无关
分析:如果方法名太长,会导致整个方法字节过长,过长后JVM就无法使用JIT编译器,只能使用解释编译器,因此性能收到影响
不止方法名,以及整个方法很大,都不会进行JIT

2021-09-14

Java中的虚引用是否不会决定对象的生命周期?

2021-09-15

G1垃圾收集算法和CMS算法相比,有哪些缺点?
image.png

2021-09-17

final关键字修饰递归方法是否可以提高执行效率么?

正常业务下面下,怎么尽量避免fgc(从jvm参数配置,代码优化方面考虑)。什么情况能达到fgc 一次都不要出现。
image.png事前:对业务主流程 进行内存合理预估
事中:使用监控工具 检测高峰期的内存变化和gc
事后:对日志分析 调U

2021-09-30

PermGen到MetaSpace这期间到底发生了什么?
1. 字符串常量池 -> java heap
2. 静态变量 -> java heap
3. 方法区(类型信息、字段、方法、常量、JIT代码缓存) -> Metaspace(no heap)

为什么会发生这些变化?
从表面上看是为了避免OOM,因为PermSize和MaxPermSize限制了永久代的上限,但是class动态加载和字符串常量增加无法预估,因此不知道设置多大,比较难受
那么换成metaspace后,可以加载class元数据不再受参数限制,而是受系统可用内存限制
>>实际上是为了合并HotSpot和JRockit的代码,JRockit从来没有所谓的永久代,也不需要开发运维人员设置永久代的大小,但是运行良好。同时也不用担心运行性能问题了,在覆盖到的测试中, 程序启动和运行速度降低不超过1%,但是这点性能损失换来了更大的安全保障

2021-10-15

jvm中对象的引用存在虚拟机栈的本地变量表中,而对象实例存储在堆中,jvm是怎么从引用定位到堆中的对象的呢?

image.png

2021-10-18

每日一题:为什么说java基本类型优于包装类型?但是POJO的类属性推荐使用包装类型。

  1. 对装箱类型使用==操作符容易出现错误。2. 当一个操作混合基本类型和装箱类型的时候,装箱类型会自动拆箱成基本类型。3. 自动装箱减少了使用装箱类型的繁琐,但是没有减少它的风险。4. 当程序进行拆箱的时候,会抛出空指针异常。5.阿里代码规约基于第四点推荐我们在pojo的属性使用包装类型。


jvm类加载的时候,是如何保证类的初始化仅被初始化一次

JVM中类加载为什么要使用双亲委派机制?