zoukankan      html  css  js  c++  java
  • jvm 常见面试题 长期更新

    1.1 举例栈溢出的情况

    1.2 调整栈的大小,就能保证不出现溢出吗?

    1.3 分配的栈内存越大越好吗?

    1.4 垃圾回收是否会设计到虚拟机栈

    1.5 方法中定义的局部变量是否线程安全 

    2.1 堆是分配对象的唯一选择吗? 

    2.2 永久代为什么要被元空间替换?

     2.3 说一下jvm内存模型有哪些,分别干什么的?

     2.4 jvm的内存分布/内存结构?堆和栈的区别?堆的结构?为什么两个servivor区?

     2.5 eden和survior的比例分配?

     2.6 jvm为什么要有新生代和老年代?

     2.7 jvm的永久代中会有垃圾回收吗?

     3.1 对象在jvm中是如何存储的?对象头中有什么内容?

     3.2 jvm是如何通过栈帧中的对象引用访问到其内部的对象实例的呢?

     4.1 常常看见变量和方法被 static 和 final 两个关键字修饰,为什么这么做?

     4.2 class类加载的过程

     5.1 synchronized和lock的区别

    
    
    
    

    1.1 举例栈溢出的情况

      StackOverflowError,不合理的递归容易造成栈溢出

    1.2 调整栈的大小,就能保证不出现溢出吗?

      可以减少出现的情况,但是不能保证栈不溢出

    1.3 分配的栈内存越大越好吗?

      理论上栈分配的越大越能避免出现栈溢出的情况,但是会挤占其他内存结构的空间

    1.4 垃圾回收是否会设计到虚拟机栈

      不会,虚拟机栈不存在GC,只存在出栈

    1.5 方法中定义的局部变量是否线程安全 

      具体情况具体分析

    public class StringBuilderTest {
        /**
         * 此方法为线程安全
         */
        public static void method1(){
            // stringBuilder 线程不安全
            StringBuilder s1 = new StringBuilder();
            s1.append("a");
            s1.append("b");
        }
        /**
         * 此方法为线程不安全
         */
        public static void method2(StringBuilder s1){
            // stringBuilder 线程不安全
            s1.append("a");
            s1.append("b");
        }
    }
    View Code

     2.1 堆是分配对象的唯一选择吗? 

      来源 : https://www.bilibili.com/video/BV1PJ411n7xZ?p=82

    在<<深入理解java虚拟机>>中关于java堆内存有这样一段描述: 随着jit编译器的发展与逃逸分析技术的逐渐成熟,栈上分配,标量替换优化技术将会导致一些微妙的变化,所有对象都分配到堆上也渐渐变得不那么绝对了.

    在java虚拟机中,对象是在java堆中分配内存的,这是一个普遍的常识,但是有一种特殊情况,那就是 如果经过逃逸分析后发现,一个对象没有逃逸出方法的话,那么就可能被优化成栈上分配,这样就无需在堆上分配内存,也无需进行垃圾回收了,这也是常见的堆外存储技术.

    此外,基于openjdk深度定制的TaoBaoVM,其中创新的GCIH(GC invisible heap)技术实现off-heap,将生命周期较长的java对象,从heap中移至heap外,并且gc不能管理gcih内部的java对象,一次达到降低gc的回收频率和提升gc回收效率的目的

    2.2 永久代为什么要被元空间替换?

      来源: https://www.bilibili.com/video/BV1PJ411n7xZ?p=98 

      随着java8的到来,hopspot vm中再也见不到永久代了,但是这并不意味着类的元数据信息也小时了,这些数据被移到了一个与堆不相连的本地内存区域,这个区域就叫元控件(Metaspace)

      由于类的元数据分配在本地内存中,元控件的最大可分配控件就是系统可用内存空间

      这项改动很有必要原因有:

      1. 为永久代设置空间大小是很难确定的. 某些场景下,如果动态加载类过多,容易产品Prem区的OOM,比如某个Web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,经常出现知名错误,而元空间和永久代之间最大的区别在于,元空间并不在虚拟机中,而是直接使用本地内存,因此默认情况下,元空间的大小仅受本地内存的限制
      2. 对永久代就行调优是很困难的. 方法区的垃圾回收(full gc)主要回收两部分内容,常量池中废弃的常量和不在使用的类,在判断类是否在使用十分耗时,将方法区到元空间可以减少full gc   

     

     2.3 说一下jvm内存模型有哪些,分别干什么的?

       

     2.4 jvm的内存分布/内存结构?堆和栈的区别?堆的结构?为什么两个servivor区?

     2.5 eden和survior的比例分配?

     2.6 jvm为什么要有新生代和老年代?

     2.7 jvm的永久代中会有垃圾回收吗?

     3.1 对象在jvm中是如何存储的?对象头中有什么内容?

      https://www.cnblogs.com/xiaodu9499/p/13275956.html

     3.2 jvm是如何通过栈帧中的对象引用访问到其内部的对象实例的呢?

      局部变量会保存对象这对内存中的位置也就是对象的reference,通过栈上的对象reference定位到对象实例

      对象访问的方式主要有两种

      1. 句柄访问:  
        1. 好处: reference中存储稳定句柄地址,对象被移动(垃圾收集时移动对象很普遍)时只会改变句柄中实例数据指针即可,reference本身不需要被修改
      2. 直接指针(Hotspot)采用  
        1. 好处: 可以直接访问到对象效率更高

     4.1 常常看见变量和方法被 static 和 final 两个关键字修饰,为什么这么做?

    1. 变量和方法于类无关,可以直接使用,使用比较方便;
    2. 强调变量内存地址不可变,方法不可继承覆写,强调了方法内部的稳定性
     

    4.2 class类加载的过程

      所谓类加载,简而言之就是讲java类的字节码文件加载到机器内存中,并在内存中构建出java类的原型-- 类模板对象,所谓类模板对象,其实就是java类在jvm内存中的快照,jvm将从字节码文件中解析出的常量池,类字段,类方法等信息存储到类模板中,这样jvm在运行期间便能通过类模板而获取java类中的任意信息,能够对java类的成员变量进行遍历,也能进行java方法的调用

    4.3 class类文件结构

    • 魔数与class文件的版本: class文件头的四个字节被称为魔数,他唯一的作用是确定这个文件是否为一个能否被虚拟机接受的calss文件,紧接着魔数的四个字节存储的事class文件的版本号,第5和第6个字节是次版本号,第7第8是主版本号
    • 常量池: 常量池可以比喻为calss文件里的资源仓库,主要存放两大类常量: 字面量和符号引用,字面量比较接近于java语言层面的常量概念,如文本字符串,被声明为final的常量值等,而符号引用则属于便于原理方面的概念主要包括下面几类常量:被模块到处或者开放的包,类和接口的全限定名,字段的名称和描述符,方法的名称和描述符,方法句柄和方法类型,动态调用点和动态常量
    • 访问标志: 用于标识一些类或者接口层次的访问信息,包括:这个class是类还是接口,是否定义为public类型,是否定义为abstact类型,如果是类的话,是否被声明为final类型等等
    • 类索引,父类索引与接口索引集合: 用来确认该类型的继承关系
    • 字段表集合: 用于标书接口中或者类中声明的变量
      • 方法表集合: 描述了类中的方法,包括方法的访问标志,名称索引,描述符索引,属性表索引等  
    • 属性表集合: 

    5.1 synchronized和lock的区别

    1. synchronized是关键字,而lock是一个接口
    2. synchronized会自动释放锁,lock需要手动释放锁
    3. synchronized是不可中断,lock可以中断也可以不中断
    4. 通过lock可以知道县城有没有拿到锁,而synchronized不能
    5. synchronized能锁住方法和代码块,lock只能锁住代码块
    6. lock可以使用读锁提高多线程的效率
    7. synchronized是非公平锁,reentrantLock可以控制是否为公平锁

     

     

     
  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/xiaodu9499/p/13264818.html
Copyright © 2011-2022 走看看