JVM快速入门(上)

  • 前言
  • JVM探究
    • 1.JVM的位置
    • 2.JVM的体系结构
    • 3.类加载器
    • 4.双亲委派机制
    • 5.沙箱安全机制
    • 6.Native(面试重点!!!)
    • 7.PC寄存器
    • 8.方法区
    • 9.栈:数据结构

前言

本文根据狂神说的JVM快速入门做了以下笔记,讲的很好的一个博主,视频链接狂神说-JVM快速入门
接下来按照他所讲的内容给大家记录一些重点!
JVM快速入门(下)

JVM探究

  • 请你谈谈你对JVM的理解?java8虚拟机和之前的变化更新?

  • 什么是OOM,什么是栈溢出StackOverError?怎么分析?

  • JVM的常用调优参数有哪些?

  • 内存快照如何抓取,怎么分析Dump文件?知道嘛?

  • 谈谈JVM中,类加载器你的认识?

1.JVM的位置

2.JVM的体系结构

栈方法区不会有垃圾回收

常说的JVM调优大部分调节的都是堆的区域

3.类加载器

​ 1.虚拟机自带的加载器

​ 2.启动类(根)加载器BOOTStrap

​ 3.扩展类加载器EXT

​ 4.应用程序加载器APP

4.双亲委派机制

  • 1.当Application ClassLoader 收到一个类加载请求时,他首先不会自己去尝试加载这个类,而是将这个请求委派给父类加载器Extension ClassLoader去完成。

  • 2.当Extension ClassLoader收到一个类加载请求时,他首先也不会自己去尝试加载这个类,而是将请求委派给父类加载器Bootstrap ClassLoader去完成。

  • 3.如果Bootstrap ClassLoader加载失败(在<JAVA_HOME>\lib中未找到所需类),就会让Extension ClassLoader尝试加载。

  • 4.如果Extension ClassLoader也加载失败,就会使用Application ClassLoader加载。

  • 5.如果Application ClassLoader也加载失败,就会使用自定义加载器去尝试加载。

  • 6.如果均加载失败,就会抛出ClassNotFoundException异常。

说白了就是从最底层的往最高层层层传递请求,查看最高级是否可以加载某个类,当无法加载时再依次往下查看,直到最底层,都没有抛出异常。

总体流程:APP–>EXT–>BOOTStrap–>EXT–>APP–>自定义加载器–>抛出异常ClassNotFoundException

5.沙箱安全机制

Java安全模型的核心就是Java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将 Java代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括什么?——CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。

所有的Java程序运行都可以指定沙箱,可以定制安全策略。

组成沙箱的基本组件

  • 字节码校验器(bytecode verifier):确保Java类文件遵循Java语言规范。这样可以帮助Java程序实现内存保护。但并不是所有的类文件都会经过字节码校验,比如核心类。
  • 类装载器(class loader):其中类装载器在3个方面对Java沙箱起作用

首先进行一个字节码校验器:确保java类文件遵循java语言规范,这样可以帮助java程序实现内存保护,但并不是所有的类文件都会经过字节码校验,比如核心类。

接下来类装载器:其中类装载器在3个方面对java沙箱起作用

1. 它防止恶意代码去干涉善意的代码。//双亲委派机制

2.它守护了被信任的类库边界。//双亲委派机制

3.它将代码归入保护域,确定了代码可以进行哪些操作。

虚拟机为不同的类加载器载入的类提供不同的命名空间,命名空间由一系列唯一的名称组成,每一个被装载的类将有一个名字,这个命名空间是由java虚拟机为每个类装载器维护的,他们互相之间甚至不可以见。

类装载器采用的机制是双亲委派模式。

说白了就是防止代码被恶意改写,保护本地系统防止被破坏,并保护内部库,并将代码归入保护域,确定代码可以进行哪些操作。

6.Native(面试重点!!!)

package com.kuang.Jvm;

public class native_test {
    public static void main(String[] args) {
        new Thread(()->{

        },"my thread name").start();
    }

    //native:凡是带了native 关键字的,说明java的作用范围达不到了,回去调用底层C语言的库!
    //会进入本地方法栈
    //调用本地方法本地接口 JNI
    //JNI作用:扩展Java的使用,融合不同的编程语言为Java所用! 最初:C、C++。
    //Java诞生的时候C、C++横行,想要立足,必须要有调用C、C++的程序~
    //它在内存区域中专门开辟了一块标记区域:Native Method Stack,登记native方法
    //在最终执行的时候,加载本地方法库中的方法通过JNI

    //Java程序驱动打印机,管理系统,掌握即可,在企业级应用中较为少见!
    //Robot()类写外挂
    private native void start0();

    //调用其他接口:  Socket..WebService~..http~

    //球球爱心网:--> 输入(PHP)--> NodeJS --> Socket --> C++ --> 游戏刷爱心
}

7.PC寄存器

程序计数器:Program Counter Register

​ 每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向像一条指令的地址,也即将要执行的指令代码),在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计

8.方法区

Method Area方法区

​ 方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法,如构造函数,接口代码也在此定义,简单说,所有定义的方法的信息都保存在该区域,此区域属于共享区间;

静态变量、常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中,但是实例变量存在堆内存中,和方法区无关

static final class类

9.栈:数据结构

​ 程序 = 数据结构 + 算法:持续学习~

​ 程序 = 框架 + 业务逻辑:吃饭

​ 栈:先进后出、后进先出()

​ 队列:先进先出、后进后出(FIFO:First Input First Output)

为什么main()方法先执行,最后结束~

栈:栈内存,主要程序的运行,生命周期和线程同步;

线程结束,占内存也就是释放,对于栈来说,不存在垃圾回收问题

一旦线程结束,栈就Over!

栈:8大基本类型 + 对象引用 + 实例的方法

栈运行原理:栈帧

栈满了 会抛出 StackOverflowError

栈 + 堆 + 方法区

画出一个对象实例化的过程在内存中:

更多推荐

JVM快速入门(上)