eden

直通大厂:Java必考系列——JVM经典面试题目(含答案)

五迷三道 提交于 2020-04-06 23:22:00
Q1:类的加载机制是什么? 答:类加载到内存中主要有5个阶段,分别为 ①加载:将Class文件读取到运行时数据区的方法区内,在堆中创建Class对象,并封装类在方法区的数据结构的过程。 ②验证:主要用于确保Class文件符合当前虚拟机的要求,保障虚拟机自身的安全,只有通过验证的Class文件才能被JVM加载。 ③准备:主要工作是在方法区中为类变量分配内存空间并设置类中变量的初始值。④解析:将常量池中的符号引用替换为直接引用。 ⑤初始化:主要通过执行类构造器的<client>方法为类进行初始化,该方法是在编译阶段由编译器自动收集类中静态语句块和变量的赋值操作组成的。JVM规定,只有在父类的<client>方法都执行成功后,子类的方法才可以被执行。在一个类中既没有静态变量赋值操作也没有静态语句块时,编译器不会为该类生成<client>方法。 Q2:有哪些类加载器,类加载器的加载模型是什么,有什么好处? 答:①主要有启动类加载器,负责加载JAVA_HOME/lib中的类库;扩展类加载器,负责加载JAVA_HOME/lib/ext中的类库;应用程序类加载器,也称系统类加载器,负责加载用户类路径上指定的类库;也可以自定义类加载器。②类加载器之间的层次关系叫做双亲委派模型,要求除了顶层的启动类加载器外其余的类加载器都应当有自己的父类加载器。一个类收到类加载请求后会层层找父类加载器去尝试加载

java虚拟机-垃圾回收算法

自闭症网瘾萝莉.ら 提交于 2020-04-02 07:27:23
在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理。但是首先需要明确,什么样的对象才能当为垃圾: 1.引用计数法:如果某个引用(即指针)指向对象,那么说明该对象还存活着的,如果没有指针与之相关联,则可以认为是垃圾。 缺点,无法解决循环引用的问题。 public class Main { public static void main(String[] args) { MyObject object1 = new MyObject(); MyObject object2 = new MyObject(); object1.object = object2; object2.object = object1; object1 = null ; object2 = null ; } } class MyObject{ public Object object = null ; } 最后面两句将object1和object2赋值为null,也就是说object1和object2指向的对象已经不可能再被访问,但是由于它们互相引用对方,导致它们的引用计数都不为0,那么垃圾收集器就永远不会回收它们。 2.可达性算法: 在java里面是使用可达性分析算法判断对象是否存活的。这个算法的基本思路就是通过一系列名为"GC Roots"的对象作为起始点

Java垃圾回收(整理)

风流意气都作罢 提交于 2020-03-25 15:11:01
Java 垃圾回收 Garbage Collection : GC ; 什么样的对象才是垃圾?怎样判断一个对象引用是不是垃圾? 垃圾回收算法: Mark-Sweep (标记 - 清除)算法, Copying (复制)算法, Mark-Compact (标记 - 整理)算法,分代收集算法 Generational Collection ,分代收集算法是目前大部分 JVM 的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代( Tenured Generation )和新生代( Young Generation ),老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法。目前大部分垃圾收集器对于新生代都采取 Copying 算法,因为新生代中每次垃圾回收都要回收大部分对象,也就是说需要复制的操作次数较少,但是实际中并不是按照 1 : 1 的比例来划分新生代的空间的,一般来说是将新生代划分为一块较大的 Eden 空间和两块较小的 Survivor 空间,每次使用 Eden 空间和其中的一块 Survivor 空间,当进行回收时,将 Eden 和 Survivor 中还存活的对象复制到另一块 Survivor 空间中

jvm分析与调优

牧云@^-^@ 提交于 2020-03-18 17:32:06
JVM的调优实际上是对GC回收的调优,减少次数 JVM模型图和GC机制: 1. 新new的对象都放在Eden区( 伊甸园嘛,创造的地方 ) 2. Eden区满或者快满的时候进行一次清理(Minor Gc),不被引用的对象直接被干掉;还有引用的对象,但是年龄比较大的,挪到S0区 3. 下次Eden区快满的时候,会进行上一步的操作,并且将Eden和S0区的年纪大的对象放到S1区【原理上随时保持S0和S1有一个是空的,用来存下一次的对象】 4. 下下次,Eden区快满的时候,会进行上一步操作,并且将Eden和S1区的年纪大的对象放到S0区【此时S1区就是空的】 5. 直到Eden区快满,S0或者S1也快满的时候,这时候就把这两个区的年纪大的对象放到Old区 6.依次循环,直到Old区也快满的时候,Eden区也快满的时候,会对整个这一块内存区域进行一次大清洗(FullGC),腾出内存,为之后的对象创建,程序运行腾地方。 清理Eden区和Survivor区叫Minor GC;清理Old区叫Major GC;清理整个堆空间—包括年轻代和老年代叫Full GC。 二.JVM参数配置 在jdk1.8以前,生产环境一般有如下配置 -XX:PermSize=512M -XX:MaxPermSize=1024M 表示在JVM里存储Java类信息,常量池和静态变量的永久代区域初始大小为512M

JVM内存管理基本知识

不问归期 提交于 2020-03-08 04:30:34
这篇本来是想好好写的,今天看了一天了的,可是,组会好像有种要悲剧的感觉啊。。暴风雨前的宁静,尽量记录一些吧。 上周把爬虫代码优化后,就哈皮哈皮的和未优化的版本一起跑了。起初,由于未优化的版本已经run了几天了,内存占用在200M多,而发现优化后的内存占用只有40M,所以很开心。但是不久就发现,优化后的版本,内存占用也会慢慢增加,大有一种“老娘给你分多少,你就要用多少”的赶脚。 用jprofiler监控,自己开发的类的对象数量都比较正常,所以决定学习一下JVM内存管理相关的东西。 JVM主要管理两种类型的内存:堆(Heap)和非堆。 按照官方的说法:“Java虚拟机具有一个堆, 堆 是 运行时 数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。” “在JVM中堆之外的内存称为 非堆 内存(Non-heap memory)”。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。 堆内存分配 JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到

JVM—垃圾回收GC算法

不想你离开。 提交于 2020-03-07 18:59:27
1 GC算法简介 算法 特点 标记-清除 分为“标记”和“清除”两个阶段 复制 可以解决效率问题,将可用的内存按容量划分为大小相等的两块。 标记-整理 先标记、再整理,最后清理 分代收集 划分新生代和老年代 2 标记-清除 2.1 流程 分为“标记”和“清除”两个阶段: (1)首先标记出所需要回收的对象(引用计数法和可达性分析,两次标记过程); (2)在标记完成后统一回收所有被标记的对象。 2.2 缺点 (1)效率问题:标记和清除两个过程的效率不高; (2)空间问题:标记清除后会 产生大量不连续的内存碎片 ,导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。 3 复制 3.1 流程 可以解决效率问题,将可用的内存 按容量划分为大小相等的两块 。 (1)每次只使用其中的一块; (2)当这一块用完了,就将还存活的对象复制到另一块上; (3)然后再把已使用的内存空间清理掉。 3.2 优点    每次对整个半区 进行内存回收,避免内存碎片问题,只需 移动堆顶指针 ,按顺序分配内存即可,实现简单,运行高效。 3.3 缺点   将 内存缩小为原来的一半 ,代价高;当对象存活率较高时需要进行较多的复制操作,效率降低。 3.4 应用   回收 新生代 ,新生代中分为Eden空间和两块较小的Survivor空间

扒一扒JVM的垃圾回收机制,下次面试你准备好了吗?

旧时模样 提交于 2020-03-03 23:41:46
一、 技术背景你要了解吧 二、 哪些内存需要回收? 2.1 引用计数算法 2.1.1 算法分析 2.1.2 优缺点 2.1.3 是不是很无趣,来段代码压压惊 2.2 可达性分析算法 2.3 Java中的引用你了解多少 2.4 对象死亡(被回收)前的最后一次挣扎 2.5 方法区如何判断是否需要回收 三、常用的垃圾收集算法 3.1 标记-清除算法 3.2 复制算法 3.3 标记-整理算法 3.4 分代收集算法 3.4.1 年轻代(Young Generation)的回收算法 3.4.2 年老代(Old Generation)的回收算法 3.4.3 持久代(Permanent Generation)的回收算法 四、常见的垃圾收集器 五、GC是什么时候触发的(面试最常见的问题之一) 5.1 Scavenge GC 5.2 Full GC 结束语 一、 技术背景你要了解吧   按照套路是要先装装X,谈谈JVM垃圾回收的前世今生的。说起垃圾回收(GC),大部分人都把这项技术当做Java语言的伴生产物。事实上,GC的历史比Java久远,早在1960年Lisp这门语言中就使用了内存动态分配和垃圾回收技术。设计和优化C++这门语言的专家们要长点心啦~~ 二、 哪些内存需要回收?   猿们都知道JVM的内存结构包括五大区域:程序计数器、虚拟机栈、本地方法栈、堆区、方法区。其中程序计数器、虚拟机栈

深入理解G1垃圾收集器

依然范特西╮ 提交于 2020-03-02 11:37:54
深入理解G1垃圾收集器 G1 GC是Jdk7的新特性之一、Jdk7+版本都可以自主配置G1作为JVM GC选项;作为JVM GC算法的一次重大升级、DK7u后G1已相对稳定、且未来计划替代CMS、所以有必要深入了解下: 不同于其他的分代回收算法、G1将堆空间划分成了互相独立的区块。每块区域既有可能属于O区、也有可能是Y区,且每类区域空间可以是不连续的(对比CMS的O区和Y区都必须是连续的)。这种将O区划分成多块的理念源于:当并发后台线程寻找可回收的对象时、有些区块包含可回收的对象要比其他区块多很多。虽然在清理这些区块时G1仍然需要暂停应用线程、但可以用相对较少的时间优先回收包含垃圾最多区块。这也是为什么G1命名为Garbage First的原因:第一时间处理垃圾最多的区块。 平时工作中大多数系统都使用CMS、即使静默升级到JDK7默认仍然采用CMS、那么G1相对于CMS的区别在: G1在压缩空间方面有优势 G1通过将内存空间分成区域(Region)的方式避免内存碎片问题 Eden, Survivor, Old区不再固定、在内存使用效率上来说更灵活 G1可以通过设置预期停顿时间(Pause Time)来控制垃圾收集时间避免应用雪崩现象 G1在回收内存后会马上同时做合并空闲内存的工作、而CMS默认是在STW(stop the world)的时候做 G1会在Young GC中使用

GC专题-查看日志

∥☆過路亽.° 提交于 2020-02-26 22:08:53
GC日志参数列表 -XX:+PrintGC 输出GC日志 -XX:+PrintGCDetails 输出GC的详细日志 -XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式) -XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800) -XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息 -Xloggc:../logs/gc.log 日志文件的输出路径 备注: GC的日志是以替换的方式(>)写入的,而不是追加(>>),如果下次写入到同一个文件中的话,以前的GC内容会被清空。可以在程序启动前或者停止时增加如下脚本,将之前gc.log转储到其它文件中。 if [ -f ${LOGS}/gc.log ]; then mv ${LOGS}/gc.log ${LOGS}/gc.log.`date +%Y%m%d%H%M%S` fi GC日志示例 除了GC日志参数外,为了更加与生产环境一致,增加了如下几个固定参数 -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -XX:MaxDirectMemorySize=1g -XX:SurvivorRatio=10 -XX:

Java 内存模型与垃圾回收

淺唱寂寞╮ 提交于 2020-02-14 23:32:22
堆空间根据垃圾回收分年轻代和老年代。 年轻代 包含为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor[1]。当回收时,将Eden和Survivor中还存活着的对象一次性地复制到另外一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor空间。这样做是为了避免内存碎片。(Eden的意思是伊甸园,新创建的对象一般位于这里) 如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1。对象在Survivor区中每“熬过”一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁),就将会被晋升到 老年代 中。 虚拟机提供了一个-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接在 老年代 分配。这样做的目的是避免在Eden区及两个Survivor区之间发生大量的内存复制(新生代采用复制算法收集内存)。 注意: 方法区在HotSpot虚拟机中也叫永久代 新生代gc叫做MinorGC 老生代gc叫做MajorGC 整个堆的gc叫做FullGC 来源: CSDN 作者: yrk0556 链接: https://blog.csdn.net/yrk0556/article/details