06.jvm面试题

1.学习方法

  process on可以搜jvm看图
  谈谈你对jvm的理解,java8虚拟机和之前的变化更新?....

2.jvm的位置

1.jre包括jvm(是个软件)可以安装在<-----windows linux mac… <—硬件体系(intel,spac)
2. .java—> classFile—>类加载器Class Loader
<—> jvm—>运行时数据区(Runtime Data Area)
包括(
方法区method area(一定有垃圾)(特殊的堆)
java栈 stack
本地方法栈 native method stack
堆 heap(一定有垃圾)(99%jvm调优在这里)
程序计数器pc
)
<—> (同级)执行引擎
<----->(同级)本地方法接口 <—本地方法库

3.类加载器

1.作用 加载class文件(把class文件加载进来,初始化这个对象)

  2.过程 new Car();  具体数据在堆 , 引用地址在栈,通过引用地址找到堆中的数据
	Car car1=new Car();
                Car car2=new Car();
                //对象不相同
                 sout(car1.hashCode())
	 sout(car2.hashCode())
                #得到类加载器的模板
	Class<? extends Car> aClass1=cart1.getClass();
               Class<? extends Car> aClass1=cart1.getClass();
          //对象相同,因为是相同的一个类模板
                 sout(aClass1.hashCode())
	 sout(aClass2.hashCode())
             (图2)
 3.加载器的分类
      1. rt.jar resources.jar启动类bootstrap root(根)加载器 rt.jar大厂改这个包  实现自定义功能
      2.ex.jar 拓展类加载器
      3.应用程序application(系统)加载器 虚拟机自带加载器 负责加载用户类路径 classpath 上所有的 jar 包和 .class 文件。
      4.自定义加载器 User ClassLoader
               Class<? extends Car> aClass1=cart1.getClass();
         ClassLoader cl= aClass1.getClassLoader();//application加载器
                 sout(cl.getParent());//拓展类
                 sout(cl.getParent().getParent());//null,c++写的获取不到
        //改写rt.jar,下面写会报不存在main方法异常
       //双亲委派机制保证安全执行代码,运行时会去加载器找
       // APP->EXC-->BOOT(最终执行),确保这几个都有这个对象
       //如果boot没有这个类,则倒着找 BOOT--->EXC--->APP
              package java.lang;
            publc class String{

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

	main(){String string=new String();}

            }
         //创建一个student类,在application系统加载器使用
      4.双亲委派机制过程(一次找缓存,一次找在父类有没有这个对象)
            1.类加载器收到类加载请求
            2.请求向上委托父类加载器去完成,一直向上委托,直到到启动类加载器
            3.启动类加载器如果能加载这个类,加载后结束,否则抛出异常通知子加载器加载
            4.重复步骤3
              Class Not Found:就是在加载器都找不到类
              Java: C++--   去指针,去内存管理
              本地方法就是调用c++的方法
              如:  new Thread.start(); //后面调用了 private native start0();看不懂的方法
                如图(2)

4.沙箱安全机制(本地代码需要权限信任,远程代码不受信任,也需要权限)(非重点)

  1. java1.1增加了安全策略(需要权限)
  2. java1.2增加的 升级为 代码签名(java生成https文件)
  3. jdk 1.6 最新安全模型(保护域),每个组都有权限,防jvm溢出,不断写文件也会StackOverFlowError
    class Test{
    main(){new Test().a();}
    public void a(){b()}
    public void b(){a()}
    }
    组成部分
    1.字节码校验器 bytecode verifier 确保java类文件符合java语法规范,实现
    java查询内存保护,并不是所有类文件都会经过字节码校验器校验,比如核心类
    (java运行时异常,语法错误)
    2.类加载器 的作用
    防止恶意代码干涉善意代码
    守护信任类库的边界
    将代码归入保护域,规定代码有哪些操作 new Robot();可以写外挂
    包括1.存取控制器 access controller控制核心api对操作系统的存取权限
    2.安全管理器 security manager
    3.安全软件包 security package
    数字证书keytools https证书
    加密

5.native(面试重点),方法区


    class Demo{
          main(){
                    new Thread(()->{sou("xxx").start();})
 
           }
    }
    //单纯的class可以写,凡是带native关键字就不是java方法(c++,python....)了,调用本地接口jni(java native interface)
    //会进入本地方法栈(登记native方法) 图3,在最终执行的时候执行
      private native void start0();    //native很少用,一般用于硬件,或者写外挂,企业级应用少见    //调用其他语言 Socket WebService http

6.程序计数器 program counter register 每个线程都有一个程序计数器是线程私有的,就是一个指针指向方法区的方法字节码(要执行指令的地址)

  非常小的内存空间,读取下一条指令 进行+1,帮助栈井井有条

7.方法区 被所有线程共享,所有字段和方法字节码,构造函数,接口代码(有抽象方法)
!!!静态常量 常量 类信息(构造方法,接口定义),运行时的常量池存储方法区中.但是实例变量存在堆内存中与方法区无关(static final,Class,常量池)
图j3 赋初值就还是在堆拿,没有就去常量池拿
请添加图片描述

包括 8大基本类型 对象引用,实例方法
栈帧(编译原理): 有栈顶和栈低都有,程序正在执行的方法一定在栈顶,子帧调用父帧,父帧调用子帧,相互调用
如图jvm4
请添加图片描述

队列:先进先出(FIFO) 程序 =数据结构+算法 : 程序=框架+业务逻辑 :吃饭
喝多了图就是栈,吃多了拉就是队列
例子: main方法调用Test.test()的方法
stack
| test() |
|main()|
~~~~~
main方法调用Test.test()的方法又调a()方法,又 a()调test()方法… | test() …| 栈溢出
| a() | | test() |
|main()|
~~~~~

       new对象的过程
          ClassLoader load Class Object to jvm 加载
          becoming Class model 变成Class模板---> 
         give off an address to  |stack| 分配地址给栈--->
         stack point to heap(heap has consitant in constant pool) 指向堆-->
         return address and constant to Class Obj 返回地址和常量给Class
         如图jvm5

在这里插入图片描述
9.虚拟机父类和堆(!!!)

虚拟机的分类 了解
   bea的JRockIt 适合军事办公,最快的jvm
   ibm的j9vm(绑定了硬件)
   hotspot(sun)主要使用

   java -version

//heap一个jvm只有一个堆内存 大小可以调节
//ideaproject旁边有个 运行的旁边,可以调节jvm传入的参数
// vm options

   1. 什么东西放到堆中?类 方法 常量 变量 引用类型的真实对象(大量的东西)
   //如果栈的引用对象失效,堆中的没有被引用的对象就是垃圾
  1. 堆内存有3个区域 主要在伊甸园和养老区
    新生区(新生代)(伊甸园yidian) young/new,轻量级gc,清理的垃圾很小
    1. 伊甸园[Eden Space]
    2.幸存区0区(不停与1区交换,不停的从伊甸园淘汰,在这里也在淘汰)
    3.幸存区1区
    养老区 (老年代)old ,重gc,full gc 清理的垃圾很大,新生区满了就清这里

     永久存储区(持久代) (perm)anent  jvm内置的对象,需要永久存储的东西
    
3.字符串可以无限长(堆内存满了), OOM错误 OutOfMemoryError 内存满了
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    main(){
String a="xxx";
          while(true){
	a+=a+ new Random().nextInt(88888);
           }


     }          

4.jdk8以后,永久存储区有个名字叫元空间

10.堆详解

1.新生区 : 类诞生和成长,甚至死亡的地方
伊甸园: 所有对象在伊甸园群生成的,满了 轻gc,如果这里对象存在引用就到下一个幸存者0,1区,伊甸园又可以存多个对象
养老区: 满了,就OOM错误
2.真理 99%的对象都是临时对象,通常不用while让他活到养老区
3.永久区(元空间),用来存放jdk自身class对象的,interface元数据,存放jre java运行时的环境或类信息(不存在垃圾回收) 非堆,逻辑上存在,物理上不存在,因为 新生代+老年代=我们设置总大小空间

    应用场景:一个启动类加载了大量的第三方jar包,tomcat部署很多应用在webapp中,
                   大量动态生成反射类,不断被加载
      jdk1.6之前  永久代, 常量池在方法区
           1.7          永久代, 慢慢退化,去永久代,常量池在堆中
           1.8           无永久代,常量池在元空间
          如图: jvm6
 代码查看内存:
   main(){
           //试图用的最大内存,单位字节 1g=1024m
           long max =Runtime.getRunTime().maxMemory();
           //初始化的总内存
            long total =Runtime.getRunTime().maxMemory();
                               //我的电脑是16g的内存 16000mb
sout("max:"+(max/(double)1024/1024)+"mb"); //3605.5M ,最大可用, 1/4
           sout("total:"+(total/(double)1024/1024)+"mb");//243.5M ,是固定的, 就是最低使用的内存总数, 1/64
          //默认情况下,分配的总内存是电脑内存的 1/4 初始化的内存是 总内存的 1/64
          //调参数 VM options ,不能太大.参数之间没有空格
                 //打印垃圾回收的内存
               -Xms1024m -Xmx1024m -XX:+PrintGCDetails 
          //查看打印有
                 1.PSYoungGen  psParallelCompact  psParallelCompact ps并行压缩
                 2.eden from to
                 3.ParOldGen
                 4.Metaspace() //也叫非堆,因为 10g=新生区+老年区

    }

4.(面试)你遇到过OOM错误吗
-----1.尝试扩大堆内存查看结果
-----2.分析内存,用工具查看那个地方的代码导致堆满了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值