内存区域-面试与分析

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直接操作字节码在运行时产生大量的类。

相关推荐
兆子龙2 小时前
深入 ahooks 3.0 useRequest 源码:插件化架构的精妙设计
javascript·面试
maplewen.3 小时前
C++11 返回值优化
开发语言·c++·面试
苏荷水3 小时前
万字总结LeetCode100(持续更新...)
java·算法·leetcode·职场和发展
UrbanJazzerati3 小时前
从零到一:用Python Tkinter打造专业的文件行删除工具(一)
后端·面试
Codiggerworld5 小时前
从字节码到JVM:深入理解Java的“一次编写,到处运行”魔法
java·开发语言·jvm
洛豳枭薰5 小时前
线上 Full GC 故障模拟
jvm·gc
不想秃头的程序员5 小时前
Vue3 子传父全解析:从基础用法到实战避坑
前端·vue.js·面试
TracyCoder1235 小时前
LeetCode Hot100(50/100)——153. 寻找旋转排序数组中的最小值
算法·leetcode·职场和发展
2501_901147836 小时前
幂函数实现的优化与工程思考笔记
笔记·算法·面试·职场和发展·php