• 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可以控制是否为公平锁

     

     

     
  • 相关阅读:
    正向代理和反向代理
    python的reduce,map,zip,filter和sorted函数
    sed和awk的简单使用
    nginx+uWSGI+django+virtualenv+supervisor发布web服务器
    nginx负载均衡
    nginx入门与实战
    python开发之virtualenv与virtualenvwrapper讲解
    Linux下的python3,virtualenv,Mysql、nginx、redis安装配置
    Linux系统基础优化及常用命令
    vim与程序员
  • 原文地址:https://www.cnblogs.com/xiaodu9499/p/13264818.html
Copyright © 2020-2023  润新知