Java是一门能够跨平台的语言,可是Java自己是不能够实现跨平台的,须要JVM实现跨平台。javac编译好后的class文件,在Windows、Linux、Mac等系统上,只要该系统安装对应的Java虚拟机,class文件均可以运行。达到”一次编译,处处运行”的效果。java
而JVM究竟是什么呢?引用百度百科对JVM的介绍:算法
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是经过在实际的计算机上仿真模拟各类计算机功能来实现的。编程
1.JVM主要包含类装载器、运行时数据区(内存模型)、执行引擎。里面内存模型有能够细分包括本地方法栈、堆、栈(线程)、方法区(元空间)、程序计数器。如图所示:数组
1.类装载器的做用就是负责加载class文件,class文件在文件开头有特定的文件标示,将class文件字节码内容加载到内存中,并将这些内容转换成方法区中的运行时数据结构而且ClassLoader只负责class文件的加载,至于它是否能够运行,则由执行引擎(Execution Engine)决定。类加载器又有四大类加载器:缓存
启动类加载器(Bootstrap ClassLoader):负责加载JRE核心类库,像JRE中的rt.jar等(C/C++);数据结构
扩展类加载器(Extension ClassLoader):负责加载JRE扩展目录ext中的jar包;多线程
系统类加载器(Application ClassLoader):负责加载ClassPath路径下的类包;架构
自定义的类加载器(User ClassLoader):只加载指定目录下的jar和class,想加载其它位置的类或jar时得自行定义类加载器;jvm
2.JVM中,对象都是在堆中分配内存空间的,栈只用于保存局部变量和临时变量,若是是对象,只保存引用,实际内存仍是在堆中。栈的特色是先进后出,假设一个main方法,里面执行了一个方法,咱们是后执行的那个方法即那个线程,可是执行完毕后,那个线程是先销毁的。每一个方法在执行的同时都会建立一个栈帧,用于存储局部变量表(存放局部变量的)、操做数栈(存放须要运算的数据)、动态连接、方法出口(执行完方法 回到main方法的位置)等信息,每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。即一个方法对应一块栈帧内存区域(存放本方法的局部变量)。ui
3.方法区存储已被虚拟机加载的类信息、常量(堆中的对象常量地址)、静态变量、即时编译器编译后的代码等数据。
4.本地方法栈和栈的做用相似,可是它服务的对象是native方法,该方法得由c语言来实现。
5.程序计数器做用是当CPU多线程切换的时候,切回到当前线程的时候,回到程序计数器计数的位置,继续执行。
新生代包括Eden加上2个survivor区,执行minor gc以后,大多数的对象会被回收,活着的进入s0,再次minor gc,活着的对象eden+s0->s1,再次minor gc,eden+s1->s0…这里虚拟机采起了分代收集的思想来管理内存,JVM给每一个对象一个对象年龄计数器,分代年龄达到15后即对象被执行了15次minor gc后移入老年代。除此以外,s区装不下的大对象也会直接进入老年代。
最后,老年代存的就是一些大对象和须要连续内存空间的对象(静态变量、缓存、线程池等),老年代满了的话,会执行Full GC垃圾收集。官网对Full GC的解释中介绍了个词”Stop-The-World”,它会把全部的应用线程停掉,这时候系统会卡掉。JVM虚拟机调优的目标就是减小full gc即减小STW。
堆里面存放new的对象和数组,Java优于其余语言一个很重要的缘由就是它能自动处理垃圾对象,也就是有垃圾回收机制(GC)。有了垃圾回收机制有几点好处编程简单,系统不容易出错。
1.什么是垃圾?
咱们把没有任何引用指向的对象或者一堆对象(循环引用)定义为垃圾。
2.系统如何定位垃圾
3.常见的垃圾回收算法
复制算法它将可用内存按容量分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活的对象复制到另一块上面,而后再把已使用过的内存空间一次清理掉。
新生代收集器:Serial、ParNew、Parallel Scavenge
老年代收集器:CMS、Serial Old、Parallel Old
整堆收集器: G1
jdk1.8 默认垃圾收集器Parallel Scavenge(新生代)+Parallel Old(老年代)