您当前的位置: 首页 >  java晴天过后 Java

Java后端开发高频面试题

java晴天过后 发布时间:2022-05-23 20:14:05 ,浏览量:2

JVM

说一下垃圾回收机制?

Java 语言中一个显著的特点就是引入了垃圾回收机制,在编写程序的时候不再需要考虑内存管理。垃圾回收机制可以有效的防止内存泄露,提高内存的内存率。

垃圾回收器通常是作为一个单独的低级线程运行,不可预知的情况下对堆中已经死亡的或者长时间没有使用的对象进行清理和回收。

回收机制的算法有:标记清除算法、复制算法、标记压缩算法等等。

描述一下垃圾回收的流程?

首先有三个代,新生代、老年代、永久代。

在新生代有三个区域:一个Eden区和两个Survivor区。当一个实例被创建了,首先会被存储Eden 区中。

具体过程是这样的:

  • 一个对象实例化时,先去看Eden区有没有足够的空间。
  • 如果有,不进行垃圾回收,对象直接在Eden区存储。
  • 如果Eden区内存已满,会进行一次minor gc。
  • 然后再进行判断Eden区中的内存是否足够。
  • 如果不足,则去看存活区的内存是否足够。
  • 如果内存足够,把Eden区部分活跃对象保存在存活区,然后把对象保存在Eden区。
  • 如果内存不足,查询老年代的内存是否足够。
  • 如果老年代内存足够,将部分存活区的活跃对象存入老年代。然后把Eden区的活跃对象放入存活区,对象依旧保存在Eden区。
  • 如果老年代内存不足,会进行一次full gc,之后老年代会再进行判断 内存是否足够,如果足够 还是那些步骤。
  • 如果不足,会抛出OutOfMemoryError(内存溢出异常)。

解释一下JVM的内存模型?

Java内存模型决定一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,定义了线程和主内存之间的抽象关系。

线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存(并不真实存在),本地内存中存储的是在主内存中共享变量的副本。

有两条规定:

  1. 线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写。
  2. 线程的工作内存是私有的,其他线程无法访问,线程变量值的传递通过主内存来完成。

GC回收的是堆内存还是栈内存?

主要管理的是堆内存。

什么时候新生代会转换为老年代?

  • Eden区满时,进行Minor GC时。
  • 对象体积太大, 新生代无法容纳时。
  • 虚拟机对每个对象定义了一个对象年龄(Age)计数器。当年龄增加到一定的临界值时,就会晋升到老年代中。
  • 如果在Survivor区中相同年龄的对象的所有大小之和超过Survivor空间的一半,包括比这个年龄大的对象就都可以直接进入老年代。

创建占大内存的对象分配到哪一代?

如果新创建的对象占用内存很大,则直接分配到老年代

新生代2个Survivor区的好处?

解决了内存碎片化问题。整个过程中,永远有一个Survivor区是空的,另一个非空的Survivor区是无碎片的。

遇到过OOM怎么解决?

我们可以修改虚拟机的参数,获取Heap Dump的文件,后缀名是.hprof。

-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=d:\jvm

之后可以使用JDK自带的一个工具jvisualvm来进行排查和定位。

Java基础

int和Integer的区别?

  • int是基本数据类型,Integer是它的包装类。
  • Integer保存的是对象的引用,int保存的变量值。
  • Integer默认是null,int默认是0。
  • Integer变量必须实例化后才能使用,而int变量不需要。

Java的基本数据类型和大小?

单位:字节
boolean(1) = byte(1)             
关注
打赏
查看更多评论