JVM常见面试题

1.JVM内存结构

jvm的内存空间可分为5个部分:程序计数器,Java虚拟机栈,本地方法栈,方法区,堆。

程序计数器(线程私有): 程序计数器是一个较小的内存区域,主要用来记录各个线程执行的字节码的地址

Java虚拟机栈(线程私有): JVM 中用于描述 Java 方法运行过程的内存模型 。每当一个 Java 方法被调用时,JVM 会为其创建一个称为"栈帧"的区域,以存储该方法执行过程中的相关信息。方法运行完后会被清空

本地方法栈(线程私有): 用于支持 Java 程序调用本地方法(Native Method)。本地方法是用其他语言(如 C 或 C++)编写的方法。

方法区(所有线程共享)/(以前都叫永久代): 方法区用于存储JVM加载的类信息、常量、静态变量等数据。它是所有线程共享的内存区域。

堆(所有线程共享): 堆是Java虚拟机所管理的内存中最大的一块存储区域。堆内存被所有线程共享。主要存放对象信息和数组。所有对象实例以及数组都要在堆上分配。垃圾收集器就是根据GC算法,收集堆上对象所占用的内存空间(收集的是对象占用的空间而不是对象本身)。

2.垃圾回收机制(GC):

堆有很多对象使用过后是需要清理的,java引用了GC垃圾回收,当Java虚拟机发觉内存资源紧张的时候,

就会自动地去清理无用对象所占用的内存空间。如果需要,可以在程序中显式地使用System.gc()来

强制进行一次立即的内存清理。

工作原理:

JVM 的垃圾回收机制中,虚拟机会根据可达性分析判断一个对象可达,对于不可达的对象 会被判断

为可回收的对象进行回收处理

3.JVM调优的方法:

1:建议用64位操作系统 Linux下64位的jdk比32位jdk要慢一些,但是吃得内存更多,吞吐量更大。

2:XMX(最大堆内存大小)和XMS(初始堆内存大小)设置一样大,MaxPermSize和MinPermSize设置一样大,这样可以减轻伸缩堆大小带来的压力。

3:调试的时候设置一些打印参数,如-XX:+PrintClassHistogram -XX:+PrintGCDetails

XX:+PrintGCTimeStamps -XX:+PrintHeapAtGc -Xloggc:log/gc.log,这样可以从gc.log里看出

一些端倪出来。

4:系统停顿的时候可能是GC的问题也可能是程序的问题,多用jmap和jstack查看,或者killall -3

java,然后查看java控制台日志,能看出很多问题。有一次,网站突然很慢,jstack一看,原来是自

己写的URLConnection连接太多没有释放,改一下程序就

5:仔细了解自己的应用,如果用了缓存,那么年老代应该大一些,缓存的HashMap不应该无限制

长,建议采用LRU算法的Map做缓存,LRUMap的最大长度也要根据实际情况设定。

6:垃圾回收时promotion failed是个很头痛的问题,一般可能是两种原因产生,第一个原因是救助

空间不够,救助空间里的对象还不应该被移动到年老代,但年轻代又有很多对象需要放入救助空间

;第二个原因是年老代没有足够的空间接纳来自年轻代的对象;这两种情况都会转向FuGC,网站

停顿时间较长。第一个原因我的最终解决办法是去掉救助空间,设置-XX:SurvivorRatio=65536

XX:MaxTenuringThreshold=0即可,第二个原因我的解决办法是设置

CMSInitiatingOccupancyFraction为某个值(假设70),这样年老代空间到70%时就开始执行

CMS,年老代有足够的空间接纳来自年轻代的对象。

7:不管怎样,永久代还是会逐渐变满,所以隔三差五重起java服务器是必要的,我每天都自动重

8:采用并发回收时,年轻代小一点,年老代要大,因为年老大用的是并发回收,即使时间长点也不

会影响其他程序继续运行,网站不会停顿。

4.堆和栈的区别:

Java堆和栈是Java虚拟机(JVM)中的两个重要概念,它们在内存管理、存储对象和执行线程等方面有明显的区别。

  1. 内存分配

:内存手动分配和释放(或垃圾回收)。堆的大小可以在运行时动态调整,通过JVM参数进行配置。。

: 自动分配和释放

  1. 生命周期

:堆的生命周期与应用程序的启动和结束相同。当应用程序启动时,堆被创建;当应用程序结束时,堆随之销毁。垃圾回收器自动管理堆内存的回收和释放。

:函数调用结束时自动销毁。

  1. 空间大小

栈的空间大小远远小于堆的。

  1. .共享性不同

栈内存是线程私有的。 堆内存是所有线程共有的。

  1. 存储内容

堆主要用于存储对象实例。堆是由垃圾回收器自动管理的,当一个对象不再被引用时,垃圾回收器会自动回收该对象占用的堆内存。

栈主要存储基本数据类型、对象引用地址和方法的局部变量

5.JVM使用命令:

java 用于启动 Java 程序。

//启动程序
java HelloWorld  
//最大堆内存为 512M
java -Xmx512m HelloWorld   

javac 用于编译 Java 源代码文件。

//编译
javac HelloWorld.java

jps 查看当前正在运行的 Java 进程

jps

jstack 打印指定 Java 进程的线程堆栈信息

//查看进程 ID 为 12345 的 Java 进程的线程堆栈
jstack 12345

jmap 查看 Java 堆内存信息或生成堆 dump 文件

//查看进程 ID 为 12345 的 Java 程序的堆内存使用情况
jmap -heap 12345

jstat 查看 JVM 的性能统计信息

//查看进程 ID 为 12345 的垃圾回收(GC)统计信息
jstat -gc 12345

面试题一天五道,持续更新中。。。。。

相关推荐
emanjusaka4 小时前
Java 中堆内存和栈内存上的数据分布和特点
java·jvm·heap·stack
我真不会起名字啊5 小时前
C++开发(软件开发)常见面试题
java·jvm·c++
一念&1 天前
python--sqlite
jvm·python·sqlite
power-辰南2 天前
架构师成长(四)之深入理解 JVM 虚拟机栈
java·jvm·架构师
xxxmine2 天前
JVM 中的各种收集器总结
jvm
叉烧钵钵鸡2 天前
【JVM详解一】类加载过程与内存区域划分
java·开发语言·jvm·后端
2401_869414622 天前
JVM 的理解
jvm
上官花雨2 天前
JVM的详细讲解
jvm
时雨h2 天前
Java即时编译器(JIT)的原理及在美团的实践经验
java·开发语言·jvm·spring