Fork me on GitHub

JVM基础

简介

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

  • 常见的JVM实现
    • Hotspot
      oracle官方,我们做实验用的JVM。
    • Jrockit
      BEA,曾经号称世界上最快的JVM;被Oracle收购,合并于hotspot。
    • TaobaoVM
      hotspot深度定制版。
    • LiquidVM
      直接针对硬件。
    • azul zing
      最新垃圾回收的业界标杆,需要收费。

javac

简介

Javac是一种编译器,将一种语言转换为另一种语言规范。编译器的作用就是将符合java语言规范的源代码转化为JVM虚拟机能够识别的字节码文件的过程。

对于java而言。javac任务就是将java源代码转换为jvm能够识别的二进制码。将.java文件转换为.class文件,这些.class文件也就是字节码文件只有JVM能够识别。

编译过程原理

image

java从编码到执行

image

JDK,JRE,JRM区别

  • JDK
    Java Development Kit.简单的说JDK是面向开发人员使用的SDK,它提供了Java的开发环境和运行环境。SDK是Software Development Kit 一般指软件开发包,可以包括函数库、编译程序等。
  • JRE
    JRE是Java Runtime Enviroment是指Java的运行环境,是面向Java程序的使用者,而不是开发者。
  • JVM
    Java Virtual Machine就是我们常说的java虚拟机,它是整个java实现跨平台的最核心的 部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是 经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。

java Dynamic Linking(动态链接)

  • 栈帧组成
    局部变量表,操作数栈,动态链接
  • java动态链接
    动态链接是一个将符号引用解析为直接引用的过程。java虚拟机执行字节码时,遇到一个操作码,操作码第一次使用一个指向另一类的符号引用,则虚拟机就必须解析这个符号引用。
    • 解析时需要执行三个基本的任务:
      • 查找被引用的类(有必要的话就装载它,一般采用延时装载)。
      • 将符号引用替换为直接引用,这样当再次遇到相同的引用时,可以使用这个直接引用,省去再次解析的步骤。
      • 当java虚拟机解析一个符号引用时,class文件检查器的第四趟扫描确保了这个引用时合法的。

内存模型

JAVA分为 栈、堆(新生代+老年代)、方法区

  • 程序计数器(Program Counter Register)
    当前线程所执行的字节码的行号 指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的 字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个 计数器来完成。

  • 栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。

  • 堆由开发人员进行设置,有默认大小设置,JAVA程序中JVM进行自动回收。
  • 方法区(Method Area)
    方法区是被所有线程共享。
    所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。
    简单说,所有定义的方法的信息都保存在该区域,此区属于共享区间。
    静态变量、常量、类信息(构造方法/接口定义) 、运行时常量池存在方法区中 。
    但是实例变量 存在堆内存中,和方法区无关。

新生区(New/Young Generation)

新生代(Young Generation),常称为YoungGen,位于堆空间;
新生区 又分为 Eden区 和 Survior(幸存区)。
Eden : 新创建的对象
Survior 0、1:经过垃圾回收,但是垃圾回收次数小于15次的对象

老年代(Old Generation)

老年代(Old Generation),常称为OldGen,位于堆空间;
Old : 垃圾回收次数超过15次,依然存活的对象

验证堆和方法区不位于同一内存中参数 -Xmx180m -Xms180m -Xmn90m -XX:MetaspaceSize=170m -XX:MaxMetaspaceSize=170m -XX:+PrintGCDetails
在JDK小于1.8的版本中字符串位于PermGen space(永久区,即方法区),1.8(包括)之后,位于堆中

JVM中内存相关参数

-Xms Java堆内存初始大小
-Xmx Java堆内存最大大小
-Xmn Java堆内存中的新生代大小,扣除它就是老年代大小
-XX:PermSize(1.8之后:-XX:MetaspaceSize) 永久代初始大小
-XX:MaxPerSize(1.8之后:-XX:MaxMetaspaceSize) 永久代最大大小
-Xss 每个线程的栈内存大小
注:通常情况下,Xms和Xmx,-XX:PermSize和-XX:MaxPerSize都会设置为一样。

-XX:MaxTenuringThreshold 多少岁进入老年代-默认15
-XX:PretenureSizeThreshold 超过多少字节的大对象直接进入老年代
-XX:HandlePromotionFailure MinorGC时,如果老年代剩余空间小于新生代对象总大小,但是如果大于之前平均进入老年代对象的大小,是否尝试进行MinorGC(默认开启)
-XX:SurvivorRatio=8 Eden区的比例
-XX:+UseParNewGC 指定使用ParNewGC垃圾回收器
-XX:ParallelGCThreads,指定ParNewGC线程数量,一般不指定ParNewGC会自动根据CPU核数适配
-XX:+PrintGCDetails 打印GC详细日志

其他

  • 使用JDK安装包安装JDK时,电脑会同时安装两套JRE,位于JDK中的这一套是运行我们开发时的普通程序,而另外的一套是运行生产环境的程序,这是因为JDK安装时自动在系统环境变量的path填充有“%SystemRoot%system32;%SystemRoot%;”参数,指向Windows/system32目录下的java.exe。
  • CA FE BA BE代表这是一个class文件

参考

https://www.cnblogs.com/williamjie/p/9558094.html;
https://blog.csdn.net/u010393809/article/details/53169255;
https://blog.csdn.net/WTUDAN/article/details/104526344?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_utm_term~default-1.pc_relevant_default&spm=1001.2101.3001.4242.2&utm_relevant_index=4;
https://www.jianshu.com/p/8abf92faa9ad;https://blog.csdn.net/chuobenggu7592/article/details/100978957;https://blog.csdn.net/K346K346/article/details/80849966?spm=1035.2023.3001.6557&utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-2defaultOPENSEARCHRate-2.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-2defaultOPENSEARCHRate-2.nonecase

posted @ 2020-05-05 22:33  晨度  阅读(645)  评论(0编辑  收藏  举报