Java面试问题收集

2021/12/12 22:21:51

本文主要是介绍Java面试问题收集,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Java面试问题收集

JVM中哪些是线程共享区?

  • Java 堆

对于大多数应用来说,Java 堆(Java Heap)是 Java 虚拟机所管理的内存中最大的一块。

Java维是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在 Java 虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配9,但是随着 JTT编译器的发展与逃逸分析技术逐渐成熟,栈上分配、标量替换P优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上也渐渐变得不是那么“绝对”了。

Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC 堆”(GarbageCollected Heap,幸好国内没翻译成“垃圾堆”)。从内存回收的角度来看,由于现在收集器基本都采用分代收集算法,所以 Java 堆中还可以细分为:新生代和老年代;再细致一点的有Eden 空间、From Survivor 空间、To Survivor 空间等。从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。

不过无论如何划分,都与存放内容无关,无论哪个区域,存储的都仍然是对象实例,进一步划分的目的是为了更好地回收内存,或者更快地分配内存。在本章中,我们仅仅针对内存区域的作用进行讨论,Java 堆中的上述各个区域的分配、回收等细节将是第 3 章的主题。

根据 Java 虚拟机规范的规定,Java 堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘空间一样。在实现时,既可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的(通过-Xmx 和-Xms 控制)。

如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出 OutOfMemoryError异常。

  • 方法区

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然 Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与Java 堆区分开来。

JVM中哪些可以作为gc root?

From:《深入理解Java虚拟机》
请添加图片描述

请添加图片描述

你们项目如何排查JVM问题

对于还在正常运行的系统:

  1. 可以使用jmap来查看IVM中各个区域的使用情况;
  2. 可以通过jstack来查看线程的运行情况,比如哪些线程阻塞、是否出现了死锁;
  3. 可以通过jstat命令来查看垃圾回收的情况,特别是fullgc,如果发现fullgc比较频繁,那么就得进行调优了;
  4. 通过各个命令的结果,或者jvisualvm等工具来进行分析;
  5. 首先,初步猜测频繁发送fullgc的原因,如果频繁发生fullgyc但是又一直没有出现内存溢出,那么表示fuligc实际上是回收了很多对象了,所以这些对象最好能在younggc过程中就直接回收掉,避免这些对象进入到老年代,对于这种情况,就要考虑这些存活时间不长的对象是不是比较大,导致年轻代放不下,直接进入到了老年代,尝试加大年轻代的大小,如果改完之后,fullgc减少,则证明修改有效;
  6. 同时,还可以找到占用CPU最多的线程,定位到具体的方法,优化这个方法的执行,看是否能避免某些对象的创建,从而节省内存

对于已经发生了OOM的系统;

  1. 一般生产系统中都会设置当系统发生了OOM时,生成当时的dump文件(-XX+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/usr/local/base);
  2. 我们可以利用jsisualvm等工具来分析dump文件
  3. 根据dump文件找到异常的实例对象,和异常的线程(占用CPU高),定位到具体的代码
  4. 然后再进行详细的分析和调试

总之,调优不是一蹴而就的,需要分析、推理、实践、总结、再分析,最终定位到具体的问题



这篇关于Java面试问题收集的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程