面试过程中,问到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调优的原则

  1. GC的时间足够小
  2. GC的次数足够少
  3. 发生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入门的更多相关文章

  1. JVM入门——运行时数据区

    这张图我相信基本上对JVM有点接触的都应该很熟悉,可以说这是JVM入门的第一课.其中的“堆”和“虚拟机栈(栈)”更是耳熟能详.下面将围绕这张图对JVM的运行时数据区做一个简单介绍. 程序计数器(Pro ...

  2. JVM入门到放弃之基本概念

    1. 基本概念 jvm 是可运行Java代码的假想计算机,包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回收堆和一个存储方法域. jvm 是运行在操作系统之上的,屏蔽了与具体操作系统平台相关的信息 ...

  3. JVM 入门三板斧

    一个JVM实例只存在一个堆内存,堆内存的大小是可以调节的.类加载器读取了类文件后,需要把类.方法.常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行,堆内存分为三部分: Young Ge ...

  4. java jvm入门 jvm什么意思 jvm调优

    接下来我会给大家讲解 国内最顶尖的jvm技术 不服来战

  5. JVM入门——JVM内存结构

    一.java代码编译执行过程 1.源码编译:通过Java源码编译器将Java代码编译成JVM字节码(.class文件) 2.类加载:通过ClassLoader及其子类来完成JVM的类加载 3.类执行: ...

  6. 2017.10.9 JVM入门学习

    1.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...

  7. JVM 入门指南

    一.什么是JVM? JVM: JVM是Java Virtual Machine的缩写,中文翻译为Java虚拟机.JVM 可以看作一台抽象的计算机,如同真实的计算机一样,它有自己的指令集和各种运行时区域 ...

  8. JVM入门必看——JVM结构

    转载自:http://blog.csdn.net/yfqnihao 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让 ...

  9. jvm入门及理解(一)——简介与体系架构

    最近,在学习java虚拟机的内容中,在此总结和记录下学到的. 一.JVM在计算机中的位置 在我们初学java时,便知道java源文件文件会先通过Java编译器编译成字节码文件,这个过程是java编译过 ...

随机推荐

  1. ZoomIt: 非PPT演示必备辅助软件

    下载地址:https://docs.microsoft.com/zh-cn/sysinternals/downloads/zoomit 使用方法: 另一个免费的屏幕标注工具:Pointofix v1. ...

  2. 子线程更新UI界面的2种方法

    一.一般我们都会在子线程完成一些耗时的操作. 1.Android中消息机制: 2.知识点: Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队, ...

  3. 画流程图挺好的软件---visio

    visio 2016 下载地址链接: https://pan.baidu.com/s/1oyfJL_QgOA7qUHOt7p8CIA 提取码: mv79 第一次做的样式图:

  4. TCP的概念

    中间节点.虚电路.失败重传 UDP:不可靠传输,并不承诺提供可靠的连接通道,所传送包完全可能失序.重复甚至丢失. TCP:端口号.三次握手建立可靠连接(第一次确认A端发送和B端接收能力,第二次确认A端 ...

  5. Tesseract训练

    最近在用Tesseract做一个图片识别的小应用,目标图像只有数字和英文字母,在实际使用过程中发现个别数识别错误,因此不得不研究学习Tesseract的训练. http://www.cnblogs.c ...

  6. 图解 (a + b) * (a + b) == a**2 + 2*a*b + b**2

    示意图

  7. numpy学习笔记(四)

    (1)NumPy - 矩阵库 NumPy 包包含一个 Matrix库numpy.matlib.此模块的函数返回矩阵而不是返回ndarray对象. matlib.empty()返回一个新矩阵,而不初始化 ...

  8. Linux系统中的计划任务

    在系统的工作管理中,我们经常会有需要去告诉电脑某些特定的时间执行一些操作,比如定时提醒工作人员需要做什么事情,或者在每天凌晨进行文件备份等等.这就需要某些命令来达成计划任务. 计划任务可以大体上分成两 ...

  9. JAVA递归实现全排列

    全排列(permutation) 排列组合概念 排列,就是指从给定n个数的元素中取出指定m个数的元素,进行排序 组合,则是指从给定n个数的元素中仅仅取出指定m个数的元素,不考虑排序 全排列 以数字为例 ...

  10. ssh 公钥无秘登录问题

    1. 验证服务启动,网络端口连接正常 可以使用nc,telnet,或者密码模式的ssh来验证 2. 验证ssh client端的配置正确 可以尝试登录另外一台主机, 或者本机自校验 3. 验证ssh ...