JVM底层知识体系

jvm类加载机制:

  加载----验证---准备----解析----初始化----使用-----卸载

一、java的理解

  1、平台无关性

 

  2、GC:垃圾回收机制,不用手动释放堆内存

  3、语言特性:泛型,反射,lemda表达式

  4、面向对象:封装、继承、多态

  5、类库:并发库,集合,网络库,IO,NIO

  6、异常处理:运行时异常、编译时异常

二、JVM如何加载.class文件

 1.1、类从编译到执行的过程:

    1、编译器将.java源文件编译为.class字节码文件

    2、ClassLoader将字节码文件转换为JVM中的Class<T>对象

    3、JVM利用Class<T>对象实例化为T对象。   

 1.2、ClassLoad的种类:

  ClassLoader在java中非常重要,所有Class都是有类加载器进行加载的,作用就是从系统外部获得Class二进制流,交给Java虚拟机进行连接,初始化等操作。

    1、BootStrapClassLoader:C++编写,加载核心库java.*

    2、ExtClassLoader:Java编写,加载扩展库javax.*

    3、AppClassLoader:Java编写,加载程序所在目录。加载类路径下(ClassPath)的类库

    4、自定义类加载器:通过继承 java.lang.ClassLoader 。通过指定的Path,去找到文件,之后将文件的二进制流读入程序中。

  1.3、双亲委派机制:避免多份同样字节码的加载

  

  1.4、类的加载方式

    隐式加载:new

    显示加载:loadClass,forName等。

    loadClass,forName的区别:Class.forName得到的class是已经初始化完成的,Class.loadClass得到的class是还没有链接的

    Spring的IOC,资源加载器获取要读入的资源后,获取bean,要使用loadClass,快速完成类的加载,属性在需要使用的地方再进行初始化

  1.5、类的装载过程

  

三、java的内存模型

  

  3.1、线程的内存模型

  

  程序计数器:

    当前线程所执行的字节码行号指示器(逻辑),

    改变计数器的值来获取下一条要执行的字节码指令,

    和线程是一对一的关系即"线程私有",对java方法计数,

    如果是native方法则计数器值为Undefined,

    不会发生内存泄漏

  虚拟机栈:

    java方法执行的内存模型

    包含多个栈帧,每个方法在执行的同时都要创建一个栈帧,用于存储局部变量表,操作数栈、动态链接、方法出口等信息

      局部变量表:包括方法执行过程中的所有变量

      操作数栈:入栈、出栈、复制、交换、产生消费变量。

  本地方法栈:

    与虚拟机栈相似、主要用于标注了native的方法。

元空间(MetaSpace)与永久代(PermGen)的区别:   

  1.6之前常量池是在永久代中,当被撑爆时会产生OutOfMemoryError异常,常量池1.7之后,将常量池放到了堆中,避免了此异常出现,1.8之后元空间代替了永久代 。

  二者都是对方法区的实现

  元空间使用本地内存,永久代使用的是jvm的内存,元空间没有常量池,1.7之后移动到了堆中

  1、字符串常量池存在永久代中,容易出现性能问题和内存溢出,

  2、类和方法的信息大小难易确定,给永久代的大小指定带来困难,

  3、永久代会为GC带来不必要的复杂性,

  4、方便HotSpot与其他JVM如Jrockit的集成。

四、java堆(Heap)

  所有线程共享的一个内存,对象的分配区域。GC管理的主要区域,新生代,老年代

五、jvm的三大性能调优参数-Xms-Xmx-Xss的含义

  -Xss:规定了每个线程虚拟机栈(堆栈)的大小

  -Xms:堆的初始值,一般设置和最大值相同,因为当heap扩容时,会产生内存抖动,影响程序运行的稳定性

  -Xmx:java堆可扩展的最大值。

六、堆和栈的区别====内存分配策略

  静态存储:编译时期确定每个数据目标在运行时的存储空间需求

  栈式存储:数据区需求在编译时未知,运行时模块入口前确定。

  堆式存储:编译时或运行时模块入口都无法确定,动态分配

堆和栈的区别:  

  联系:引用对象、数组时,栈里定义变量保存堆中目标的首地址

大方向区别:

  管理方式:栈自动释放,堆需要GC

  空间大小:栈比堆小

  碎片相关:栈产生的碎片远小于堆

  分配方式:栈支持静态和动态分配,而堆仅支持动态分配

  效率:栈的效率比堆高

大白话区别:

  栈内存:程序是在栈内存中运行,占中存的是基本数据类型和堆中对象的引用,栈是运行时的单元(程序是如何执行,或者如何处理数据),一个线程一个独立的线程栈

  堆内存:程序运行所需要的大部分数据保存在栈内存中,堆中存储的是对象,堆是存储单元,堆是一块共享的内存,堆解决的是数据存储问题(数据怎么放,放在哪),所有线程共享堆内存

猜你喜欢

转载自www.cnblogs.com/guanyuehao0107/p/12039411.html