内存区域-面试与分析

1.运行时数据区是什么?

虚拟机在执行Java程序的过程将它所管理的内存划分为若干不同的数据区,这些区域有各自的用途、创建和销毁时间。

线程私有:程序计数器、Java虚拟机栈、本地方法栈

线程共享:Java堆,方法区

2.程序计数器是什么?

程序计数器是一块较小的内存空间,可以看作当前线程所执行字节码的行号指示器。字节码解释器工作时通过改变计数器的值选取下一条执行指令。

分支、循环、跳转、线程恢复等功能都需要依赖计数器完成。

如果线程正在执行Java方法,计数器记录正在执行 的虚拟机字节码指令地址。如果时本地方法,计数器值为Undefined.

3.堆的作用是什么?

堆是虚拟机所管理的内存中最大的一块,被所有线程共享的,在虚拟机启动时创建。堆用来存放对象实例,Java里几乎所有对象实例都在堆分配内存。堆可以处于 物理上不连续的内存空间,逻辑上应该连续,但对于数组这样的大对象,多数虚拟机实现处于简单,存储高效的考虑会要求连续的内存空间。

堆既可以被实现成固定大小 ,也可以是可扩展的。

4.方法区的作用是什么?

方法区用于存储被虚拟机加载的类型信息,常量,静态变量,即时编译器编译后的代码缓存等数据

JDK8之前使用永久实现方法区,容易内存溢出,因为永久带有MaxPermSize上限,即使不设置也有默认大小。

JDK7把永久代的字符串常量池、静态变量等移出,JDK8中永久代完全废弃,改用在本地内存中实现的元空间代替。

5.运行时常量池的作用是什么?

相对于Class文件常量池的一个重要特征是动态性,Java不希望常量只有编译期才能产生,运行期间也可以将新的常量放入池中,这种特性利用较多的是String的intern方法。

6.直接内存是什么?

频繁使用的内存,不属于运行时数据区,而且可能导致内存溢出

JDK1.4新加入了NIO这种基于通道与缓存区的IO,可以使用Native函数库直接范培对外内u才能,通过一个堆里的DirectByteBuffer对象作为内存的引用进行操作,避免了Java堆和Native堆来回复制数据。

直接内存的分配不受Java堆大小的限制,但还是会受到本机总内存及处理器寻址空间限制,一般配置虚拟机参数会根据实际内存设置参数信息

-》但是会忽略直接内存,会导致内存区域总和大于物理内存限制,导致 动态扩展出现OOM

7.内存溢出和内存泄漏的区别?

内存溢出OutOfMemory,指程序在申请内存时,没有足够的内存空间供其使用

内存泄漏 Memory Leak,指程序在申请内存后,无法释放已申请的内存空间,内存泄漏最终i将导致内存溢出。

8.栈溢出的原因?

HotSpot不区分虚拟机和本地方法栈,设置本地方法栈大小的参数没有意义,栈容量只能由-Xss参数 来设定,存在两种异常:

StackOverflowError:如果线程请求的栈深度大于虚拟机所允许的深度 ,将抛出StackOverflowError,例如一个递归方法不断调用自己。该异常有明确错误堆栈可供分析,容易定位到问题所在。

OutOfMemoryError:如果JVM栈可以动态扩展 ,当扩展无法申请到足够内存时会抛出OutOfMemoryError。HotSpot不支持虚拟机栈扩展,所以除非在创建线程申请内存时因为无法获得足够内存而出现OOM,否则在线程运行时是不会因为扩展而导致溢出的。

运行时常量池溢出的原因?

String.intern方法;如果常量池中有等于此String对象的字符串,返回池中这个字符串的String对象的引用,否则将此String对象包含的字符串添加到常量池并返回此String对象的引用。

在while死循环中调用intern方法导致运行时常量池溢出。

JDK7之后不会出现该问题,因为存放在永久代的字符串常量池已经被移至堆中。

方法区溢出原因?

方法区主要存放类型信息,如类名,访问修饰符,常量池,字段描述,方法描述等。只要不断在运行时产生大量类,方法区就会溢出

eg:使用JDK反射或CGLib直接操作字节码在运行时产生大量的类。

相关推荐
嘟嘟w1 小时前
JVM(Java 虚拟机):核心原理、内存模型与调优实践
java·开发语言·jvm
鹏北海2 小时前
从“版本号打架”到 30 秒内提醒用户刷新:一个微前端团队的实践
前端·面试·架构
G皮T3 小时前
【Java】Java 运行时数据区域(一):名词概念
java·jvm·runtime·运行时·运行时数据区域
小白程序员成长日记3 小时前
2025.11.21 力扣每日一题
算法·leetcode·职场和发展
小年糕是糕手4 小时前
【C++】C++入门 -- inline、nullptr
linux·开发语言·jvm·数据结构·c++·算法·排序算法
韭菜炒大葱4 小时前
从回调到async/await:JavaScript异步编程的进化之路
前端·javascript·面试
七夜zippoe4 小时前
JVM调优实战:从GC日志分析到参数配置(Xmx, Xms, XX:+)
java·jvm·gc·jit·垃圾回收器
IUGEI5 小时前
【后端开发笔记】JVM底层原理-内存结构篇
java·jvm·笔记·后端
努力学算法的蒟蒻6 小时前
day17(11.18)——leetcode面试经典150
算法·leetcode·面试
未若君雅裁7 小时前
JVM基础总结
java·jvm·java-ee