美团到店事业群-平台技术部 校招预备队qq群 821133476
入群第一时间获知校招岗位开放信息,第一时间获知补录岗位开放信息,快人一步!
内推二维码:
https://www.cnblogs.com/CATHY-MU/gallery/image/387231.html
如果后端岗位还没开放,可以先加群 821133476等第一时间通知
面试被问到.class文件结构,赶紧背这几条!
https://www.nowcoder.com/discuss/684230?source_id=profile_create_nctrack&channel=-1
面试被问到jdk监控工具,赶紧背这几条!
https://www.nowcoder.com/discuss/685100?source_id=profile_create_nctrack&channel=-1
面试被问到操作系统,赶紧背这几条!
https://www.nowcoder.com/discuss/686243?source_id=profile_create_nctrack&channel=-1
面试被问到垃圾回收,赶紧背这几条!
JVM把内存划分成了如下几个区域:
1.方法区(Method Area) 2.堆区(Heap) 3.虚拟机栈(VM Stack) 4.本地方法栈(Native Method Stack) 5.程序计数器(Program Counter Register)
方法区
所有线程共享
类加载器加载完类文件就是放在这。
已被虚拟机加载的类信息(构造函数、类中的字段和方法)、
(final定义的)常量、静态变量、
即时编译器编译后的代码
运行时常量池(Runtime Constant Pool)是方法区的一部分,用于存储编译器生成的常量和引用。一般来说,常量的分配在编译时就能确定,但也不全是,比如String类维护了一个常量池,如果调用的字符已经在常量池中,则直接返回常量池中的地址,否则新建一个常量加入池中。(区分:运行时常量池和string常量池是两个)
JDK1.7及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。
方法区超过允许大小时,会抛出OutOfMemory:PermGen Space异常。方法区对应持久带,GC条件苛刻。GC主要针对常量池的回收和已加载类的卸载。
堆
所有线程共享
存储new出来的对象和数组
虚拟机启动时创建
gc的主要区域,分为新生代(eden s1 s2) 老生代 持久代(1.8移除,替换为使用物理内存的元空间,原因:难确定永久代应该制定多大,会增加gc复杂度)
虚拟机栈
位于操作系统内存
线程私有,生命周期和线程一样。随着线程销毁,内存自动释放,不需要GC。
每个方法被执行时产生一个栈帧,方法被调用时,栈帧入栈,方法调用结束时,栈帧出栈。
栈帧用于存储局部变量表、动态链接、操作数和方法出口等信息。
局部变量表中存储基本数据类型及对象的引用地址等,内存空间在编译期间就确定了,运行时不再改变。
如果线程调用的栈深度大于虚拟机允许的最大深度,则抛出StackOverFlowError;不过大多数虚拟机都允许动态扩展虚拟机栈的大小,所以线程可以一直申请栈,直到内存不足时,抛出OutOfMemoryError。
虚拟机栈属于线程私有是为了保证线程中的局部变量不被别的线程访问到。
本地方法栈
位于操作系统内存
线程私有,生命周期和线程一样。随着线程销毁,内存自动释放,不需要GC。线程私有是为了不被别的线程访问到局部变量。
存放内容同虚拟机栈,区别是存储的是虚拟机栈存储Java方法、本地方法栈存储native方法的执行状态。
在很多虚拟机中(如Sun的JDK默认的HotSpot虚拟机),会将虚拟机栈和本地方法栈一起使用。
程序计数器
位于CPU上
线程私有,生命周期和线程一样。随着线程销毁,内存自动释放,不需要GC。
在JVM解释字节码(.class)文件时,存储当前线程执行的字节码行号(字节码地址),只是一种概念模型,各种JVM所采用的方式不一样。
字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。
如果正在执行的是native方法,程序计数器为空。
唯一不会抛出OutOfMemoryError
全部评论
(0) 回帖