Java工程师面试1000题91-100

91、JVM的类加载机制是什么?有哪些实现方式?

类加载机制:类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法去内,然后在堆区创建一个java.lang.Class对象,用来封装在方法区内的数据结构。类的加载最终是在堆区内的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

类加载有三种方式:

1)命令行启动应用时候由JVM初始化加载;

2)通过Class.forName()方法动态加载;

3)通过ClassLoader.loadClass()方法动态加载。

92、JVM调优的常见命令行工具有哪些?JVM常见的调优参数有哪些?

JVM调优的常见命令工具包括:

1)jps命令用于查询正在运行的JVM进程,

2)jstat可以实时显示本地或远程JVM进程中类装载、内存、垃圾收集、JIT编译等数据

3)jinfo用于查询当前运行着的JVM属性和参数的值。

4)jmap用于显示当前Java堆和永久代的详细信息。

5)jhat用于分析使用jmap生成的dump文件,是JDK自带的工具。

6)jstack用于生成当前JVM的所有线程快照,线程快照是虚拟机每一条线程正在执行的方法,目的是定位线程出现长时间停顿的原因。

JVM常见的调优参数包括:

-Xmx——指定java程序的最大堆内存, 使用java -Xmx5000M -version判断当前系统能分配的最大堆内存

-Xms——指定最小堆内存, 通常设置成跟最大堆内存一样,减少GC

-Xmn——设置年轻代大小。整个堆大小=年轻代大小 + 年老代大小。所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。

-Xss——指定线程的最大栈空间, 此参数决定了java函数调用的深度, 值越大调用深度越深, 若值太小则容易出栈溢出错误(StackOverflowError)

-XX:PermSize——指定方法区(永久区)的初始值,默认是物理内存的1/64, 在Java8永久区移除, 代之的是元数据区, 由-XX:MetaspaceSize指定

-XX:MaxPermSize——指定方法区的最大值, 默认是物理内存的1/4, 在java8中由-XX:MaxMetaspaceSize指定元数据区的大小

-XX:NewRatio=n——年老代与年轻代的比值,-XX:NewRatio=2, 表示年老代与年轻代的比值为2:1

-XX:SurvivorRatio=n——Eden区与Survivor区的大小比值,-XX:SurvivorRatio=8表示Eden区与Survivor区的大小比值是8:1:1,因为Survivor区有两个(from, to)

93、ConcurrentHashMap加锁机制是什么,详细说一下?

HashTable容器在竞争激烈的并发环境下表现出效率低下的原因,是因为所有访问HashTable的线程都必须竞争同一把锁,那假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。

94、在重写equals方法时,需要遵循哪些约定,具体介绍一下?

重写equals方法时需要遵循通用约定:自反性、对称性、传递性、一致性.、非空性

1)自反性:对于任何非null的引用值x,x.equals(x)必须返回true。---这一点基本上不会有啥问题

2)对称性:对于任何非null的引用值x和y,当且仅当x.equals(y)为true时,y.equals(x)也为true。

3)传递性:对于任何非null的引用值x、y、z。如果x.equals(y)==true,y.equals(z)==true,那么x.equals(z)==true。

4) 一致性:对于任何非null的引用值x和y,只要equals的比较操作在对象所用的信息没有被修改,那么多次调用x.eqals(y)就会一致性地返回true,或者一致性的返回false。

5)非空性:所有比较的对象都不能为空。

95、Java内存堆和栈区别?

栈内存用来存储基本类型的变量和对象的引用变量,堆内存用来存放Java中的对象,无论是成员变量,局部变量,还是类变量,他们指向的对象都存储在堆内存中。栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,可以将栈内存理解为线程的私有内存,堆内存中的对象对所有线程可见,堆内存中的对象可以别所有线程访问。如果栈内存没有可用的空间存储方法调用和局部变量,JVM会抛出java.lang.StackOverFlowError,如果是堆内存没有可用的空间存储生成的对象,JVM会抛出java.lang.OutOfMemoryError。栈的内存要远远小于堆内存,如果你使用递归的话,那么你的栈会很快就充满了,-Xss选项设置栈内存的大小。-Xms选项可以设置堆的开始时的大小。

96、介绍一下Java里的四引用。

  • 强引用:StrongReference,强引用是使用最普遍的引用,如果一个对象具有强引用,那垃圾回收器绝对不会回收它,当内存空间不足时,Java虚拟机宁可抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
  • 软引用:SoftReference,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
  • 弱引用:WeakReference,弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中
  • 虚引用:PhantomReference,虚引用在任何时候都可能被垃圾回收器回收,主要用来跟踪对象被垃圾回收器回收的活动,被回收时会收到一个系统通知。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

97、介绍一下GC回收机制

  • Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的。GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控
  • Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理
  • 可以调用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() ,但JVM可以屏蔽掉显示的垃圾回收调用

98、介绍一下MinorGC&FullGC

  • Minor GC通常发生在新生代的Eden区,在这个区的对象生存期短,往往发生GC的频率较高,回收速度比较快,一般采用复制-回收算法;
  • Full GC/Major GC 发生在老年代,一般情况下,触发老年代GC的时候不会触发Minor GC,所采用的是标记-清除算法。

 

99、介绍一下Java的内存分配和回收策略

  • 结构(堆大小 = 新生代 + 老年代 ):
    • 新生代(1/3)(初始对象,生命周期短):Eden 区、survivior 0、survivior 1( 8 : 1 : 1)
    • 老年代(2/3)(长时间存在的对象)
  • 一般小型的对象都会在 Eden 区上分配,如果Eden区无法分配,那么尝试把活着的对象放到survivor0中去(Minor GC)
    • 如果survivor0可以放入,那么放入之后清除Eden区
    • 如果survivor0不可以放入,那么尝试把Eden和survivor0的存活对象放到survivor1中
      • 如果survivor1可以放入,那么放入survivor1之后清除Eden和survivor0,之后再把survivor1中的对象复制到survivor0中,保持survivor1一直为空。
      • 如果survivor1不可以放入,那么直接把它们放入到老年代中,并清除Eden和survivor0,这个过程也称为分配担保(Full GC)
  • 大对象、长期存活的对象则直接进入老年代
  • 动态对象年龄判定
  • 空间分配担保,Full GC...

100、引起类加载操作的五个行为都是什么?

  • 遇到new、getstatic、putstatic或invokestatic这四条字节码指令
  • 反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化
  • 子类初始化的时候,如果其父类还没初始化,则需先触发其父类的初始化
  • 虚拟机执行主类的时候(有 main(string[] args))
  • JDK1.7 动态语言支持
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值