java程序员面试(六)

Java平台与内存管理

  1. 为什么说java是平台独立性语言

    • 平台独立性是指可以在一个平台上编写和编译代码,而在其他平台上运行。
    • 保证java平台独立性,一是字节码,二是java虚拟机。
    • 解释执行过程分为三步:代码的装入、代码的校验、代码的执行。装入代码的工作由类装载器完成,被装入的代码由字节码校验器校验。
    • java字节码的执行也分为两种方式:即时编译方式与解释执行方式。
  2. Java平台与其他语言平台有哪些区别?

    • java平台是一个纯软件的平台,这个平台可以运行在一些基于硬件的平台之上。Java平台主要包含两个模块:JVM和Java API.
    • JVM是一个虚构出来的计算机,用来把Java编译生成的中间代码转换为机器可以识别的编码运行。它有自己完善的硬件架构,例如处理器、堆栈、寄存器等等,还具有相应的指令系统,它屏蔽了与具体操作系统平台相关的信息。
    • Java API是Java为了方便开发人员进行开发而设计的,它提供了许多非常有用的接口。这些接口也是用Java语言编写的,并且运行在JVM上。
  3. JVM加载class文件的原理机制是什么?

    • Java语言是一种具有动态性的解释型语言,类只有被加载到JVM后才能运行,当运行指定程序时,JVM会编译生成.class文件按照需求和一定的规则加载到内存中,并组织成一个完整的java程序。
    • 加载的过程由类加载器来完成,具体来说,就是ClassLoader和它的子类来实现的。类加载器本身也是一个类,其实质是把类文件从硬盘读到内存中。
    • 类加载的方式分为隐式加载与显示加载两种,隐式加载指的是程序在使用new等方式创建对象时,会隐式地调用类的加载器把对应的类加载到JVM中。显示的加载是指通过直接调用class.forName()方法来把所需的类加载到JVM中。
    • 在java语言中可以把类分为3类:系统类、扩展类和自定义类。Java针对这3种不同的类提供了三种不同的类加载器。
    • Bootstrap Loader 负责加载系统类(jre/lib/rt.jar的类)
    • ExtClassLoader 负责加载扩展类(jar/lib/ext/*.jar的类)
    • AppClassLoader 负责加载应用类 (classpath指定的目录或jar中的类)
    • 以上三个类是如何协调工作来完成类的加载呢?其实,它们通过委托的方式实现的。具体而言,就是当有类需要被加载时,类加载器会请求父类来完成这个载入工作,父类会使用其自己的搜索路径来搜索需要被加载的类,如果搜索不到,才会由子类按照其搜索路径来搜索待加载的类。
    • 类加载主要分为以下3步:

      • 装载。根据查找路径找到相对应的class文件,然后导入。
      • 链接。链接有可以分为三个小的步骤。1.检查。检查待加载的class文件的正确性。2.准备。给类中的静态变量分配存储空间。3.解析。将符号引用转换成直接引用。
      • 初始化。 对静态变量和静态代码块执行初始化工作。
  4. 什么是GC

    • 垃圾回收(Garbage Collection ,GC)是一个非常重要的概念,它的主要 作用是回收程序中不在使用的内存。
    • Java语言提供了垃圾回收器来自动检测对象的作用域,可自动地吧不在被使用的存储空间释放掉。
    • 具体而言,垃圾回收器要负责完成3项任务:分配内存、确保被引用对象的内存不被错误地回收、回收不再被引用的对象的内存空间。
    • 对于垃圾回收器来说,它使用有向图来记录和管理堆内存中的所有对象,通过这个有向图就可以识别哪些对象是“可达的”,哪些对象是“不可达的“(没有引用变量引用它就是不可达的),所有”不可达“对象都是可悲垃圾回收的。
    • 垃圾回收算法:1.引用计数法 2.追踪回收算法 3.压缩回收算法 4.复制回收算法 5.按代回收算法
  5. Java是否存在内存泄漏

    • 内存泄漏是指一个不再被程序使用的对象或变量还在内存中占用存储空间。
    • 在java语言中,判断一个内存空间是否符合垃圾回收的标准有两个:第一,给对象赋予了空值null,以后没有再被使用过。第二、给对象赋予了新值,重新分配了内存空间。
    • 一般来讲,内存泄漏主要有两种情况:一是在堆中申请的空间没有被释放;二是对象已不再使用,但还仍然在内存中保留着。
    • 垃圾回收机制的引入可以有效地解决第一种情况;而对于第二种情况,垃圾回收机制则无法保证不再使用的对象会被释放。因此Java语言中的内存泄漏主要指的是第二种情况。
    • Java语言中,容易引起内存泄漏的原因很多。1.静态集合类 2.各种连接 3.监听器 4.变量不合理的作用域
  6. Java中的堆和栈有什么区别

    • 在Java语言中,堆与栈都是内存中存放数据的地方。
    • 变量分为基本数据类型和引用类型,基本数据类型的变量以及对象的引用变量,其内存都分配在栈上,变量出了作用域就会自动释放,而引用类型的变量,其内存分配在堆上或者常量池(字符串常量和基本数据类型常量)中,需要通过new等方式进行创建。
    • 栈内存主要用来存放基本数据类型与引用变量。栈内存的管理是通过压栈和弹栈操作来完成的,以栈帧为基本单位来管理程序的调用关系,每当有函数调用时,都会通过压栈方式创建新的栈帧,每当函数调用结束后都会通过弹栈的方式释放栈帧。
    • 堆内存用来存放运行时创建的对象。一般来讲,通过new关键字创建出来的对象都存放在堆内存中。
    • 由于JVM是基于堆栈的虚拟机,而每个Java程序都运行在一个单独的JVM实例上,每个实例唯一对应一个堆,一个Java程序内的多个线程也就运行在同一个JVM实例上,因此这些线程之间会共享堆内存。鉴于此,多线程在访问堆中的数据时需要对数据进行同步。
    • 从堆和栈的功能以及作用来比较,堆主要用来存放对象的,栈主要是用来执行程序的。相较于堆,栈的存取速度更快,但栈的大小和生存期必须是确定的,因此缺乏一定的灵活性。而堆却可以在运行时动态地分配内存。生存期不用提前告诉编译器,但这也导致了其存取速度的缓慢。

本文链接:

https://heyzen.club/index.php/J/303.html
1 + 6 =
快来做第一个评论的人吧~