07-JVM快速入门

JVM快速入门

常见面试题:

  • 请谈谈你对JVM的理解,java8虚拟机和之前相比有哪些变化?
  • 什么是OOM,什么是栈溢出StackOverFlowError?怎么分析?
  • JVM的常用调优参数有哪些?
  • 内存快照如何抓取,怎么分析Dump文件?
  • 谈谈JVM中,你对类加载器的认识

JVM的体系结构

image-20211019092449468

类加载

类加载器

类加载器作用:加载Class文件

image-20211019105140674

package com.wang.jvm;

public class Car {
    public int age;
    public static void main(String[] args) {
        //类是模板,对象是具体的

        Car car1 = new Car();
        Car car2 = new Car();
        Car car3 = new Car();

        System.out.println(car1.hashCode());
        System.out.println(car2.hashCode());
        System.out.println(car3.hashCode());

        Class<? extends Car> aClass1 = car1.getClass();
        Class<? extends Car> aClass2 = car1.getClass();
        Class<? extends Car> aClass3 = car1.getClass();

        System.out.println(aClass1.hashCode());
        System.out.println(aClass2.hashCode());
        System.out.println(aClass3.hashCode());

    }
}

image-20211019105835695

1.虚拟机自带的加载器

2.启动类(根)加载器(Bootstrap classLoader)

3.扩展类加载器(ExtClassLoader)

4.应用程序加载器(AppClassLoader)

image-20211019110250642

package com.wang.jvm;

public class Car {
    public int age;
    public static void main(String[] args) {
        //类是模板,对象是具体的

        Car car1 = new Car();
        Car car2 = new Car();
        Car car3 = new Car();

        System.out.println(car1.hashCode());
        System.out.println(car2.hashCode());
        System.out.println(car3.hashCode());

        Class<? extends Car> aClass1 = car1.getClass();

        ClassLoader classLoader = aClass1.getClassLoader();
        System.out.println(classLoader);// AppClassLoader 应用程序加载器
        System.out.println(classLoader.getParent());// ExtClassLoader 扩展类加载器  \jre\lib\ext
        System.out.println(classLoader.getParent().getParent());// null 1.不存在 2.java程序获取不到 rt.jar
    }
}

image-20211019111104871

双亲委派机制

package java.lang;

public class String {
    //双亲委派机制:保证安全
    // APP->EXC->BOOT(最终执行)

    public String toString(){
        return "Hello";
    }

    public static void main(String[] args) {
        String s = new String();
        s.toString();
    }
    /*
    1.类加载器收到类加载的请求
    2.将这个请求向上委托给父类加载器去完成,一直向上委托,直到启动类加载器
    3.启动加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则抛出异常,通知子加载器进行加载
    4.重复步骤3
    Class Not Found ~

    null:java调用不到  C、C++
    java(C++--):C++去掉繁琐的东西,指针,内存管理
      */
}

image-20211019124448794

沙箱安全机制

Java安全模型的核心就是Java沙箱(sandbox),沙箱是一个限制程序运行的环境。

沙箱机制就是将Java代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证代码的有效隔离,防止对本地系统造成破坏。

组成沙箱的基本组件:

  • 字节码校验器(bytecode verifier):确保Java类文件遵循Java语言规范(格式)。这样可以帮助Java程序实现内存保护。但并不是所有的类文件都会经过字节码校验,比如核心类(核心类已经测试过了,不需要再校验)
  • 类装载器(class loader):其中类装载器在3个方面对Java沙箱起作用
    • 它防止恶意代码去干涉善意的代码(双亲委派机制);
    • 它守护了被信任的类库边界;
    • 它将代码归入保护域,确定了代码可以进行哪些操作。

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

1.从最内层JVM自带类加载器开始加载,外层恶意同名类得不到加载从而无法使用;
2.由于严格通过包来区分了访问域,外层恶意的类通过内置代码也无法获得权限访问到内层类,破坏代码就自然无法生效。

  • 存取控制器(access controller):存取控制器可以控制核心API对操作系统的存取权限,而这个控制的策略设定,可以由用户指定。
  • 安全管理器(security manager):是核心API和操作系统之间的主要接口。实现权限控制,比存取控制器优先级高。
  • 安全软件包(security package):java.security下的类和扩展包下的类,允许用户为自己的应用增加新的安全特性,包括:
    • 安全提供者
    • 消息摘要
    • 数字签名 keytools
    • 加密
    • 鉴别

Native

package com.wang.jvm;

public class Demo {
    public static void main(String[] args) {
        new Thread(()->{
        },"my thread name").start();
    }

    private native void start0();
    // native:凡是带了native关键字的,说明java的作用范围达不到了,回去调用底层c语言的库!
    // 会进入本地方法栈
    // 调用本地方法接口 JNI
    // JNI作用:扩展Java的使用,融合不同的编程语言为Java所用!
    // java诞生之初,C和C++横行,想要立足,必须要有调用C、C++的程序
    // 所以在内存区域中专门开辟了一块标记区域:Native Method Stack(本地方法栈),登记native方法
    // 在最终执行的时候,加载本地方法库中的方法通过JNI
    // Java程序驱动打印机,管理系统,掌握即可,在企业级应用中较为少见

    //调用其它接口:Socket,WebService~,http~
}

PC寄存器

程序计数器:Program Counter Register

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

方法区

Method Area 方法区

方法区是被所有线程共享,所有字段和方法字节码,以及一些特殊方法,所有定义的方法的信息都保存在该区域,此区域属于共享空间

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

23

posted @ 2021-10-29 16:19  萘汝  阅读(43)  评论(0编辑  收藏  举报
我发了疯似的祝你好!