深入理解java虚拟机

这个文章是自己看书记录用于以后复习用的,不适用于大家学习,如果不小心搜索到,那现在可以直接关闭了

面试题收集:

1、你知道哪些或者你们线上使⽤什么GC策略?它有什么优势,适⽤于什么场景?
2、Java类加载器包括⼏种?它们之间的⽗⼦关系是怎么样的?双亲委派机制是什么意思?有什么好处?
3、如何⾃定义⼀个类加载器?你使⽤过哪些或者你在什么场景下需要⼀个⾃定义的类加载器吗?
4、堆内存设置的参数是什么?
5、Perm Space中保存什么数据?会引起OutOfMemory吗?
6、做GC时,⼀个对象在内存各个Space中被移动的顺序是什么?
7、你有没有遇到过OutOfMemory问题?你是怎么来处理这个问题的?处理 过程中有哪些收获?
8、JDK 1.8之后Perm Space有哪些变动? MetaSpace⼤⼩默认是⽆限的么? 还是你们会通过什么⽅式来指定⼤⼩?
9、jstack 是⼲什么的? jstat 呢?如果线上程序周期性地出现卡顿,你怀疑可 能是 GC 导致的,你会怎么来排查这个问题?线程⽇志⼀般你会看其中的什么 部分?
10、StackOverflow异常有没有遇到过?⼀般你猜测会在什么情况下被触发?如何指定⼀个线程的堆栈⼤⼩?⼀般你们写多少?

一 运行时数据区域

1.1.1 程序计数器

线程私有,用于记录当前线程运行到的位置,以便随时恢复线程

1.1.2 Java虚拟机栈

线程私有,包括栈帧,局部变量表,操作数栈,动态链接,方法出口
局部变量表保存8种基本类型的局部变量,以及引用类型的指针
栈帧对应着一个方法

1.1.3 本地方法栈

与Java虚拟机栈类似,但是是用于支持native方法的执行的,在hotspot虚拟机中,Java虚拟机栈与本地方法栈共用

1.1.4 Java 堆

所有线程共享,垃圾收集器的主要区域,可以分为新生代和老年代,新生代又分为Eden space, From survivor space , To survivor space。
从内存分配的角度看,可以分为多个线程私有的的分配缓冲区
通过-Xmx -Xms 控制大小

1.1.5 方法区

存放类信息,常量,静态变量,即时编译器编译后的代码等数据
--XX:MaxPermSize 指定上限
这一区域的垃圾回收目标主要是针对常量池的回收和类型的卸载

1.1.6 运行时常量池

这是方法区的一部分,用于存放编译期生成的各种字面量和符号引用

1.1.7 对象的创建

  • 检查new指令的参数是否能在常量池中定位到一个类的符号引用,并且检查类是否已经被加载
  • 为新生对象分配内存空间
    指针碰撞:java堆规整,Serial,ParNew等带Compact过程的收集器使用
    空闲列表:java堆不规整,需要维护列表,CMS等Mark-Sweep算法收集器使用
    如何保证内存分配的原子性:
    方法一:CAS+失败重试的方法
    方法二:使用-XX:+/-UseTABLE来指定使用本地线程分配缓冲

1.1.8 对象的内存布局

对象在内存中可以分为:对象头(Header)实例数据(Instance Data)和对齐填充(Padding)
对象头(储存对象自身的运行时数据):哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳,类型指针(有的虚拟机可能没有),如果是数据对象,还要记录长度
实例数据:默认分配策略会把同大小的分配到一起,父类的变量会出现在子类之前,但是子类中较窄的变量也可能会插入到父类的间隙中去。
对齐填充:HotSpot VM 要求对象的起始地址必须是8字节的整数倍,所有要填充

1.1.9 对象的访问定位

句柄访问:java堆中划分一块内存来作为句柄池,reference保存的是句柄池的地址,句柄池中包含对象的实例数据指针和对象的类型指针。缺点是多一次访问,优点是reference不用变。
直接指针访问:reference直接保存对象实例数据地址,对象头中包含元类型数据地址
HotSpot使用的是直接访问的方式

二 垃圾收集器与内存分配策略

2.1 对象已经死了吗

引用计数法
可达性分析算法:GC Roots 包括虚拟机栈中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象、本地方法栈中JNI引用的对象

2.2 引用类型

强引用:普通new Object()产生的引用
软引用:内存溢出时会回收
弱引用:下次GC时一定会回收
虚引用:无法通过虚引用来找到一个对象,这种引用只是想在对象回收时收到一个通知

2.3 finalize()方法

对象第一次可达性分析,如果没有与GC ROOTs相连,则会调用finalize方法,在finalize方法中可以自救,但是finalize方法只会被调用一次

2.4 回收方法区

方法区回收的效果不好,主要是回收废弃常量和无用的类
废弃常量:与堆中的对象类似,没有任何引用的对象
无用的类:必须要满足以下三个条件,才会被回收

  • 该类的实例已经全被回收
  • 加载该类的ClassLoader已经被回收
  • 该类的Class对象被回收

参数-Xnoclassgc 参数可以控制是否回收无用的类

2.5 垃圾回收算法

标记清除法(Mark-Sweep):算法分为标记-清除两个阶段

  • 效率不高
  • 容易产生碎片

复制算法:每次只用一块,用完时把对象复制到另一块中

  • 实际使用的内存只有原来的一半
  • HotSpot新生代Eden:Survivor = 8:1 需要老年代担保

标记整理算法(Mark-Compact): 先标记,然后把存活对象往一边移动

分代回收的思想:新生代使用复制算法,老年代使用标记-清理或者标记-整理算法

2.6 HotSpot 算法实现

2.6.1.Serial收集器

虚拟机在Client模式下新生代的默认收集器,单线程,采用复制算法

2.6.2 ParNew收集器

与Serial收集器一样,只是回收新生代时采用的是多线程
这是Server模式下新生代的首选收集器
-XX:SurvivorRatio:Eden区:两个Survivor区 的比值
-XX:ParallelGCThreads : 指定线程的数量
-XX:+UseParNewGC强制指定使用这种收集器

2.6.3 Parallel Scavenge 收集器

新生代收集器,与ParNew一样使用的是复制算法,多线程,但是这个收集器的目标是使垃圾收集的时间尽量短
-XX MaxGCPauseMillis:控制最大垃圾收集时间
-XX:GCTimeRatio:用来控制吞吐量
-XX:UseAdptiveSizePolicy:自动调用新生代大小,Eden和Survivor区的比例

2.6.4 Serial Old 收集器

Serial 收集器的老年代版本,单线程,使用标记整理算法

2.6.5 Parallel Old 收集器

Parallel Scavenge 收集器的老年代版本,多线程,标记-整理算法

2.6.5 CMS收集器

以最短停顿时间为目标,标记清除算法
步骤一:初始标记:从GC Roots 递归找到所有存活对象
步骤二:并发标记:GC Roots Tracing过程
步骤三:重新标记:修正并发标记期间的变动
步骤四:并发清除:清除对象
只有初始标记和重新标记会暂停用户线程
缺点:

  • 对CPU资源比较敏感、占用(CPU+3) / 4 的线程
  • 无法处理浮动垃圾(并发清理阶段用户线程新产生的垃圾),不能等到老年代几乎满了才运行(默认68%,-XX:CMSInitiatingOccupancyFraction设置阀值),可能会出现Concurrent Mode Failure、
  • 有碎片问题 -XX:+UseCMSCompactAtFullCollection设置FullGC后整理碎片,-XX:CMSFullGCsBeforeCompation设置多少次不整理后就会整理一次
2.6.6 对象分配策略
  • 优先在Eden区分配
  • 大对象直接进入老年代: -XX:PretenureSizeThreshold 参数用于设置直接进入老年代的阀值,这个参数只对Serial和ParNew收集器
  • 长期存活对象进入老年代:-XX: MaxTenuringThreshold参数设置进入老年代的对象年龄
  • 对象动态年龄判断:若则在某个年龄,Survivor空间中相同年龄所有对象大小总和大于Survivor一半,则年龄大于或等于该的年龄的对象全进入老年代

三 常用监控分析工具

  • jps:显示指定系统内所有的hotspot虚拟机进程
  • jstat:用于收集HotSpot虚拟机各方面的数据
  • jinfo:显示虚拟机配置信息
  • jmap:生成虚拟机内存转储快照文件
  • jhat:用于分析headmap文件
  • jstack:显示虚拟机线程快照
3.1 jps
  • -q:只输出虚拟机ID,忽略其他参数
  • -m:输出启动主类时传递给main的参数
  • -l:输出主类的全类名,如果执行的是jar包,输出jar包位置
  • -v:输出jvm参数
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容