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编译过 ...
随机推荐
- verilog 中task用法
1.任务定义 任务定义的形式如下: task task_id; [declaration] procedural_statement endtask 其中,关键词 task ...
- 使用SQL SERVER 来自动发送邮件
可以使用SQL SERVER 来发送自动邮件,主要是使用SQL SERVER 的dbo.sp_send_dbmail 存储过程(在msdb数据库中). 具体步骤如下: Step1: 编写要发送的邮件内 ...
- Creating and using a blendspace in c++
转自:https://forums.unrealengine.com/development-discussion/c-gameplay-programming/104831-creating-and ...
- chrome的console功能
Console的常用用法: 1:显示信息 常用的有 console.log(),console.info(),console.warn(),console.error() 2:占位符 3:查看对象的信 ...
- mysql集群搭建--韩国庆
按照我给大家提供的步骤,一步一步来,你就能配好mysql集群环境 什么是mycat 简单的说,MyCAT就是: •一个彻底开源的,面向企业应用开发的“大数据库集群” •支持事务.ACID.可以替代My ...
- ubuntu10.04换官方源
ubuntu10.04LTS官方已经不再维护,导致部分软件.库文件等下载有问题,可换以下源地址解决问题 deb http://old-releases.ubuntu.com/ubuntu lucid ...
- windows server 2003产生的 Minidmp蓝屏文件分析求助
在机房运行的四台服务器中均出现了蓝屏dmp文件,经过整理发现CDMS主备服务器最近(2018年1月开始)蓝屏的dmp很多.经过自己的学习分析发现不足以找到先关的原因和处理方法,希望得到大牛们的帮助.以 ...
- Redis单机版分布式锁实现
转载自:https://www.cnblogs.com/linjiqin/p/8003838.html Redis分布式锁的正确实现方式 前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基 ...
- Git 记不住命令
Git 记不住命令 每次用每次查 真棒 git log --stat --author=someone # git查询某个人修改记录 git log filename # fileName相关的com ...
- 记一次nginx强制将https请求重定向http
公司要做小程序,但是发现小程序只允许https请求 所以查了查资料使用nginx重定向请求得方式做 以下是过程: 阿里云ssl证书管理控制台申请ssl证书 下载nginx 证书: 解压后得到后缀为ke ...