JVM入门
面试过程中,问到JVM一脸懵逼,在github看了一些文章,感觉质量不错,整理了一下希望大家不吝赐教。
目前主流的jdk采用解释与编译混合执行的模式,其JIT技术采用分层编译,极大地提升了Java的执行速度
刚学习Java的时候,提到Java是一次编写,到处运行”(Write once, run anywhere),当时只是粗略记住了,那么怎么实现的呢?
1.如何实现跨平台?
首先,计算机工程领域任何问题,都可以通过增加一个中间层来解决。Java的中间码就是“字节码(Bytecode)”,Java所有的指令有200个左右一个字节可以存储256种不同指令的信息。代码执行过程中,JVM将字节码解释执行,屏蔽对底层操作系统的依赖,JVM也可以将字节码编译执行,如果是热点代码,会通过JIT动态地编译为机器码,提高执行效率。
2.字节码的执行流程
字节码必须通过类加载到JVM环境中,才可以执行。执行有三种模式:
1.解释执行
2.JIT编译执行
3.JIT编译与解释混合(大多数主流JVM采用的方案)
混合执行模式的优势在于解释器在启动时先解释执行,省去编译时间。随着时间推进,JVM通过热点代码统计分析,识别高频方法的调用、循环体、公共模块等,基于强大的JIT动态编译技术,将热点代码转换成机器码,直接交给CPU执行。JIT作用就是将字节码动态地编译成可以直接发送给处理器指令执行的机器码。
即时编译流程
3.类怎么加载的(双亲委派机制)
首先,低层次的当前类加载器,不能覆盖更高层次类加载器已将加载的类。如果低层次的类想加载一个未知类,要非常礼貌的向上级询问:请问这个类已经加载了吗? 被询问的高层次类加载器会自问两个问题:
- 我是否已经加载过此类?
- 如果没有可否加载此类
如果回答都是否定的,才可以加载这个未知类。
4.JVM调优的原则
- GC的时间足够小
- GC的次数足够少
- 发生Full GC的周期足够长
前两个是相悖的,要想GC时间小必须要一个更小的堆,要保证GC的次数足够少,必须保证更大的堆,只能取其平衡
(1)针对JVM堆的设置,通过 -Xms -Xmx 限定其最小值和最大值,为了防止,垃圾收集器在最小最大之间收缩堆而产生额外的时间,通常把最大最小设为相同的值
(2) 年轻代和老年代将根据默认的比例(1:2)分配堆内存,可以通过调整二者之间的比率NewRadio调整二者的大小。
(3)年轻代和老年代设置多大才算合理?
没有固定答案。
整个JVM内存大小 = 年轻代大小 + 老年代大小 + 持久代大小。
持久代大小一般为64M,增大年轻代后,将会减小老年代的大。此值对系统性能影响较大,Sun官方推荐将年轻代调整为整个堆的 3/8
(4)配置较好的机器上(多核,大内存),可以为老年代选择并行收集算法 -XX:+UseParallelOldGC ,默认为 Serial 收集
(5) 线程堆栈的设置:每个线程默认会开启1M的堆栈。用于存放栈帧、调用参数、局部变量等,减小这个值能生成更多的的线程,但操作系统对一个进程内的线程数有限制,不能无限生成,一般在3000~5000左右
5. 对象分配规则
- 对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC.
- 大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。避免在Eden区和Survior区之间发生大量的内存拷贝
- 长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,对象经过一次Monior GC对象会进入Survivor区,之后每经过一次Minor GC那么对象年龄增加1,直到达到阀值后进入老年代
- 动态判断对象的年龄。如果Survivor区中有相同年龄的对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象直接进入老年代。
- 空间分配担保。每次进行Monitor GC时,JVM会计算Survivor区移动至老年区的对象的平均大小,如果这个值大于老年区的剩余值的大小则进行一次 Full GC,如果小于就检查HandlerPromonitorFailure设置,如果true则只进行Monitor GC,false则进行Full GC
JVM入门的更多相关文章
- JVM入门——运行时数据区
这张图我相信基本上对JVM有点接触的都应该很熟悉,可以说这是JVM入门的第一课.其中的“堆”和“虚拟机栈(栈)”更是耳熟能详.下面将围绕这张图对JVM的运行时数据区做一个简单介绍. 程序计数器(Pro ...
- JVM入门到放弃之基本概念
1. 基本概念 jvm 是可运行Java代码的假想计算机,包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回收堆和一个存储方法域. jvm 是运行在操作系统之上的,屏蔽了与具体操作系统平台相关的信息 ...
- JVM 入门三板斧
一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的.类加载器读取了类文件后,需要把类.方法.常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行,堆内存分为三部分: Young Ge ...
- java jvm入门 jvm什么意思 jvm调优
接下来我会给大家讲解 国内最顶尖的jvm技术 不服来战
- JVM入门——JVM内存结构
一.java代码编译执行过程 1.源码编译:通过Java源码编译器将Java代码编译成JVM字节码(.class文件) 2.类加载:通过ClassLoader及其子类来完成JVM的类加载 3.类执行: ...
- 2017.10.9 JVM入门学习
1.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...
- JVM 入门指南
一.什么是JVM? JVM: JVM是Java Virtual Machine的缩写,中文翻译为Java虚拟机.JVM 可以看作一台抽象的计算机,如同真实的计算机一样,它有自己的指令集和各种运行时区域 ...
- JVM入门必看——JVM结构
转载自:http://blog.csdn.net/yfqnihao 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让 ...
- jvm入门及理解(一)——简介与体系架构
最近,在学习java虚拟机的内容中,在此总结和记录下学到的. 一.JVM在计算机中的位置 在我们初学java时,便知道java源文件文件会先通过Java编译器编译成字节码文件,这个过程是java编译过 ...
随机推荐
- 编辑器-vim
编辑器之神-vim vi简介 vi是“Visual interface”的简称,它在Linux上的地位就仿佛Edit程序在DOS上一样.它可以执行输出.删除.查找.替换.块操作等众多文本操作,而且用户 ...
- 【CentOS】PostgreSQL安装与设定
本教程适合Centos6.7或者RedHat. PostgreSQL安装 1.Postgresql安装包确认 yum list postgresql* postgresql-server.x86_64 ...
- python基础知识8---条件和循环
阅读目录 一.if语句 1.1 功能 1.2 语法 1.2.1:单分支,单重条件判断 1.2.2:单分支,多重条件判断 1.2.3:if+else 1.2.4:多分支if+elif+else 1.2. ...
- 更新 TeX Live 软件包
这个 TeX Live 软件,你得时常更新一下,不然会遇到一些由软件包自身 Bug 导致的编译问题.比如,这次我使用 Beamer 软件包写演示文稿,就遇到问题了,结果发现是软件包自身存在的问题.安装 ...
- 使用Excel自动生成sql语句
在近一段日子里,进入了新的项目组,由于项目需要,经常要将一些Excel表中的数据导入数据库中,以前并没有过多的接触过数据导入与数据处理,对于我来说比较痛苦,今天下午花了几个小时处理数据,但是同事给我提 ...
- 应用程序调用dll动态库,参数有vector时崩溃的问题
引用:http://blog.csdn.net/guoliushui/article/details/43017339 今天跟同事遇到了一个问题,问题背景: 一个动态库Tst.dll: 一个应用程序A ...
- 尝试 Markdown 写测试用例
我的原帖https://testerhome.com/topics/9412 大家都知道我们社区的帖子提倡用Markdown格式编写,正好项目进入稳定期,尝试用Markdown写下测试用例.有几个目的 ...
- [UE4]AttachToComponent的AttachmentRule
官方文档 KeepRelative 将当前相对转换保持为新父级的相对转换 KeepWorld 自动计算相对变换,使附着的组件保持相同的世界变换 SnapToTarget 捕捉转换到附着点
- MySQL MGR+ Consul之数据库高可用方案
背景说明: 基于目前存在很多MySQL数据库单点故障,传统的MHA,PXC等方案用VIP或者DNS切换的方式可以实现.基于数据库的数据强一致性考虑,采用MGR集群,采用consul服务注册发现 ...
- cefsharp插入自定义JS
string script_1 = "document.getElementsByTagName('head')[0].appendChild(document.createEleme ...