abuxeds
发表于 2021-4-21 21:19
kankan看看
kobe1029
发表于 2021-4-21 21:51
666666666666666666
lipton1993
发表于 2021-4-21 22:37
2021年最新 Elasticsearch零基础教程
rendongya
发表于 2021-4-21 22:42
2021年最新 Elasticsearch零基础教程
呆萌钟
发表于 2021-4-21 22:46
1.Java的内存模型?
• 虚拟机栈:是Java方法执行的内存模型。Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表、操作数栈方法返回地址和一些额外的附加信息。栈也是线程私有的。
• 本地方法栈:本地方法栈和虚拟机栈所发挥的作用是很相似的,线程私有,它们之间的区别不过是 虚拟机栈为虚拟机执行Java方法(字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。Sun HotSpot 直接就把本地方法栈和虚拟机栈合二为一。本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。
• 程序计数器:一块较小的内存空间,它可以是看作当前线程所执行的字节码的行号指示器,线程私有,此内存区域是唯一一个在JVM规范中没有规定任何OutOfMemoryError情况的区域。
• 堆:堆是jvm内存管理的最大的一块区域,此内存区域的唯一目的就是存放对象的实例,所有对象实例与数组都要在堆上分配内存。它也是垃圾收集器的主要管理区域。java堆可以处于物理上不连续的空间,只要逻辑上是连续的即可。线程共享的区域。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将抛出OutOfMemoryError异常。
• 方法区:是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。方法区是堆的一个逻辑部分,为了区分Java堆,它还有一个别名Non-Heap(非堆)。相对而言,GC对于这个区域的收集是很少出现的。当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
2. Java8做了什么修改?
• 方法区变化:1.8同1.7比,最大的差别就是:元数据区取代了永久代,就是JDK8没有了PermSize相关的参数配置了。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在虚拟机中,而是使用本地内存。
• 运行时常量池变化:在近三个JDK版本(1.6、1.7、1.8)中, 运行时常量池的所处区域一直在不断的变化,在JDK1.6时它是方法区的一部分;1.7又把他放到了堆内存中;1.8之后出现了元空间,它又回到了方法区
3. 堆分为哪几部分?
• 年轻代 : 常常又被划分为Eden区和Survivor(From Survivor To Survivor)区(Eden空间、From Survivor空间、To Survivor空间(空间分配比例是8:1:1)
• 老年代
• 永久代 (jdk 8已移除永久代)
4. JVM的对象分配在哪个区,Class对象分配在哪个区?
都是堆区
5. Java栈什么时候会发生内存溢出,Java堆呢?
• 栈内存溢出:栈溢出就是方法执行是创建的栈帧超过了栈的深度。那么最有可能的就是方法递归调用产生这种结果。
• 堆内存溢出:堆中主要存储的是对象。如果不断的new对象则会导致堆中的空间溢出
6. JVM有哪几种引用类型?不同引用类型之间的区别?
• 强引用:当对象被强引用类型引用时,对象不会被gc释放
○ 强引用是接触最多的,平时写一个A a = new A();就是将jvm栈中的引用内存a指向堆中新创建的A对象,这个就是强引用类型。
• 软引用:当对象被软引用类型引用,且没有被强引用类型引用时,对象在jvm内存足够时gc不会被释放,在内存不足时gc会将其释放
○ 比如集合中存储的对象
• 弱引用:当对象被弱引用类型引用,且没有被强引用类型引用时,无论jvm内存是否充足,对象都会被释放
• 虚引用:当对象仅被虚引用类型引用时,对象类似于没有引用,随时会被释放
7. jvm如何判断对象是否是垃圾对象?
• 引用计数算法:引用计数算法就是在对象中添加了一个引用计数器,当有地方引用这个对象时,引用计数器的值就加1,当引用失效的时候,引用计数器的值就减1。当引用计数器的值为0时,jvm就开始回收这个对象。
○ 简单的来说,在JVM中的栈中,如果栈帧中指向了一个对象,那么堆中的引用计数器的值就会加1,当栈帧这个指向null时,对象的引用计数器就减1。
○ 这种方法虽然很简单、高效,但是JVM一般不会选择这个方法,因为这个方法会出现一个问题:当对象之间相互指向时,两个对象的引用计数器的值都会加1,而由于两个对象时相互指向,所以引用不会失效,这样JVM就无法回收。
• 可达性分析法:针对引用计数算法的BUG,JVM采用了另一种方法:定义一个名为"GC Roots"的对象作为起始点,这个"GC Roots"可以有多个,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,即可以进行垃圾回收
8. GC 可达性分析中哪些算是GC ROOT?
• 虚拟机栈(栈帧中本地变量表)中引用的对象;
• 方法区中类静态属性引用的对象;
• 方法区中常量引用的对象;
• 本地方法栈中JNI(Native方法)引用的对象。
9. java GC算法,什么时候会触发minor gc,什么时候会触发full gc?
• Minor GC触发条件:当Eden区满时,触发Minor GC
• Full GC触发条件
○ 调用System.gc时,系统建议执行Full GC,但是不必然执行
○ 老年代空间不足
○ 方法去空间不足
○ 通过Minor GC后进入老年代的平均大小大于老年代的可用内存
○ 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
10. JVM有哪些垃圾回收算法,对应的收集器有哪些?
• 标记清除算法:算法分为两部分,标记和清除。首先标记出所有需要被回收的对象,然后在标记完成后统一回收掉所有被标记的对象。
○ 缺点
§ 标记和清除的效率不是很高
§ 标记和清除后会产生很多的内存碎片,导致可用的内存空间不连续,当分配大对象的时候,没有足够的空间时不得不提前触发一次垃圾回收
• 复制算法:算法将可用的内存空间分为大小相等的两块,每次只是用其中的一块,当这一块被用完的时候,就将还存活的对象复制到另一块中,然后把原已使用过的那一块内存空间一次回收掉。这个算法常用于新生代的垃圾回收。
○ 复制算法解决了标记-清除算法的效率问题,以空间换时间,但是当存活对象非常多的时候,复制操作效率将会变低,而且每次只能使用一半的内存空间,利用率不高。
• 标记整理算法:算法分为三部分:一是标记出所有需要被回收的对象;二是把所有存活的对象都向一端移动;三是把所有存活对象边界以外的内存空间都回收掉。
○ 标记-整理算法解决了复制算法多复制效率低、空间利用率低的问题,同时也解决了内存碎片的问题。
• 分代回收算法:根据对象生存周期的不同将内存空间划分为不同的块,然后对不同的块使用不同的回收算法。一般把Java堆分为新生代和老年代,新生代中对象的存活周期短,只有少量存活的对象,所以可以使用复制算法,而老年代中对象存活时间长,而且对象比较多,所以可以采用标记-清除和标记-整理算法。
11. 新生代分为几个区?使用什么算法进行垃圾回收?为什么使用这个算法?
• 新生代分区:Eden、From Survivor、To Survivor,大小比例为:8:1:1;
○ To Survivor:保留的是MinorGC的幸存者;
○ From Survivor:保留的是上次GC的幸存者,在这次作为被扫描者;
• 使用复制算法;
• 因为复制算法的实现,导致复制算法适用于对象较少的情况下,当Eden区的内存被填满,会触发minorGC ,Eden区对象会从Eden转移到Survivor区,随着年龄的增加再到老年代。
12. 结合堆区,描述下创建对象的过程,Eden区放不下的时候会怎么办?
• new的对象先放伊甸园区,此区有大小限制
• 当伊甸园的空间填满时,程序又需要创建对象,触发GC(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。再加载新的对象放到伊甸园区
• 然后将伊甸园中的剩余对象移动到幸存者0区
• 如果再次触发垃圾回收,此时上次幸存下来的放到幸存者0区的,如果没有回收,就会放到幸存者1区
• 如果再次经历垃圾回收,此时会重新放回幸存者0区,接着再去幸存者1区
• 啥时候能去养老区呢?可以设置次数。默认是15次。·可以设置参数:-XX:MaxTenuringThreshold=进行设置
• 当老年区内存不足时,再次触发GC:full GC,进行养老区的内存清理
• 若养老区执行了Major GC之后发现依然无法进行对象的保存,就会产生OOM异常
• 当新建对象需要的内存过大,超过eden的剩余内存时,会看老年代的剩余内存是否装的下,如果装的下会放到老年代,如果放不下,会报OOM
13. 说下young gc的过程?
• new的对象先放伊甸园区,此区有大小限制
• 当伊甸园的空间填满时,程序又需要创建对象,触发GC(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。再加载新的对象放到伊甸园区
• 然后将伊甸园中的剩余对象移动到幸存者0区
• 如果再次触发垃圾回收,此时上次幸存下来的放到幸存者0区的,如果没有回收,就会放到幸存者1区
• 如果再次经历垃圾回收,此时会重新放回幸存者0区,接着再去幸存者1区
14. 如果一个对象触发young gc后空间还不够,怎么办?
当新建对象需要的内存过大,超过eden的剩余内存时,会看老年代的剩余内存是否装的下,如果装的下会放到老年代,如果放不下,会报OOM
15. 什么对象会进老年代?
• 一定次数的minor gc后:常规对象被创建之后是存储在年轻代的Eden区,每一个对象都有年龄,在YGC后,survivor1区还存活的对象的年龄全部+1,当对象年龄达到15时,被移交到老年代,15是系统默认的,我们可以通过JVM参数-XX:MaxTenuringThreshold来设置
• minor gc后survivor放不下:在MinorGC之后存活的对象超过了survivor区的大小,会将这些对象直接转移到老年代
• survivor内同年龄对象大小:如果再survivor区,有某一年龄的对象的总大小超过了survivor区大小的50%,则将这个年龄以上的对象全部转移到老年代
• 大对象:所谓大对象就是指需要比较大的连续内存空间的Java对象,比如很长的字符串或数组,我们可以通过JVM参数-XX:PretenureSizeThreshold指定大对象的容量,单位是字节。
16. GC默认年龄多大进入老年代?
15
17. JVM中的老年代在什么情况下会触发GC?
• System.gc()
• 空间分配担保时,老年代空间不足了
• 正常大龄对象进入老年代,老年代剩余空间小于晋升到老年代的对象的平均大小
18. 谁进行空间担保?
JVM使用分代收集算法,将堆内存划分为年轻代和老年代,两块内存分别采用不同的垃圾回收算法,空间担保指的是老年代进行空间分配担保
19. 什么是空间分配担保?
• 在发生Minor GC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,
• 如果大于,则此次Minor GC是安全的
• 如果小于,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果HandlePromotionFailure=true,那么会继续检查老年代最大可用连续空间是否大于历次晋升到老年代的对象的平均大小,如果大于,则尝试进行一次Minor GC,但这次Minor GC依然是有风险的;如果小于或者HandlePromotionFailure=false,则改为进行一次Full GC。
20. 为什么要进行空间担保?
是因为新生代采用复制收集算法,假如大量对象在Minor GC后仍然存活(最极端情况为内存回收后新生代中所有对象均存活),而Survivor空间是比较小的,这时就需要老年代进行分配担保,把Survivor无法容纳的对象放到老年代。老年代要进行空间分配担保,前提是老年代得有足够空间来容纳这些对象,但一共有多少对象在内存回收后存活下来是不可预知的,因此只好取之前每次垃圾回收后晋升到老年代的对象大小的平均值作为参考。使用这个平均值与老年代剩余空间进行比较,来决定是否进行Full GC来让老年代腾出更多空间。
21. GC停顿原因,如何降低停顿?
• 高速率创建对象:如果你的应用程序的对象创建率很高,那么为了跟上它,垃圾回收率也将会很高。高垃圾回收率也会增加 GC 停顿时间。因此,优化应用程序以创建更少的对象是减少长 GC 停顿的有效策略。
• 年轻代空间不足:当年轻代过小时,对象会过早地提升到老年代。从老年代收集垃圾比从年轻代收集垃圾要花费更多的时间。因此,增加年轻代的大小有可能减少长时间的 GC 停顿
• 选择 GC 算法:GC 算法对 GC 停顿时间有很大的影响。如果你是 GC 专家或打算成为一个(或你的团队中的有人是 GC 专家),你可以调整 GC 参数配置以获得最佳 GC 停顿时间。如果你没有大量的 GC 的专业知识,那么我建议使用 G1 GC 算法,因为它有自动调节的能力
Aceslup
发表于 2021-4-22 01:07
又使一套es入门,不要让人失望啊
1989guojie
发表于 2021-4-22 01:11
RE: 2021年最新 Elasticsearch零基础教程 [修改]RE: 2021年最新 Elasticsearch零基础教程 [修改]RE: 2021年最新 Elasticsearch零基础教程 [修改]
makeitbetter
发表于 2021-4-22 09:15
2021年最新 Elasticsearch零基础教程
irenb
发表于 2021-4-22 19:24
2021年最新 Elasticsearch零基础教程
sdly_oct
发表于 2021-4-22 19:29
Elasticsearch零基础教程