大家好,我是鸭鸭!
辞退人的理由很多,鸭鸭最近又刷到了一个离谱的:应届毕业生因为拒绝周末跑 10 公里被辞退。
公司给的理由非常 冠 冕 堂 皇 :这件事反映出来的是缺乏主动思考,没有管理潜力,不符合公司对管培生的要求。
公司对管培生的要求?鸭鸭只知道,管培生的要求肯定不是下班后 5 公里户外跑步,更不是周末早上 7 点进行 10 公里的户外跑步。
当事人是今年应届生,按他的帖子内容,他是今年 7 月刚刚入职的,在8月底,连续加班 12 天,每天工作时长达 13、14 个小时的前提下,他拒绝了公司的两次跑步活动,随即便被公司管理约谈劝退。
……
找工作这件事多多少少也看点运气,一个好的工作环境,不仅看薪资待遇,也要看公司文化,这件事的当事人同学已经提起了劳动仲裁,鸭鸭希望大家都能少遇到这样的离谱事件。
还是再刷一道面试题,努力多拿一些 offer ,让自己在求职中更多一些选择的余地!
来看看今天鸭鸭为大家准备的面试题吧!
JVM 的内存区域是如何划分的?
回答重点
Java 虚拟机运行时数据区分为方法区、堆、虚拟机栈、本地方法栈、程序计数器。
1)方法区(Method Area):
- 存储类信息、常量、静态变量和即时编译器(JIT)编译后的代码。
- 属于线程共享区域,所有线程共享方法区内存。
- 在 JDK 8 之前,HotSpot 使用永久代(PermGen)来实现方法区,JDK 8 之后被元空间(Metaspace)取代,元空间使用的是直接内存(Native Memory)。
2)堆(Heap):
- 用于存放所有线程共享的对象和数组,是垃圾回收的主要区域。
3)虚拟机栈(JVM Stack):
- 每个线程创建一个栈,用来保存局部变量、操作数栈、动态链接、方法出口信息等。
- 局部变量表中存储的是基本数据类型(如 int、float)以及对象引用。
- 栈是线程私有的,生命周期与线程相同。
4)本地方法栈(Native Method Stack):
- 为本地方法服务,使用 JNI(Java Native Interface)调用的本地代码在此区域分配内存。
- 和虚拟机栈类似,也是线程私有的。
5)程序计数器(Program Counter Register):
- 是一个小的内存区域,保存当前线程执行的字节码指令的地址或行号。
- 每个线程都有一个独立的程序计数器,属于线程私有。
还有一个直接内存(Direct Memory) 这里也提一下,它属于 JVM 之外的内存区域:
- 由 NIO 库通过
ByteBuffer
直接分配的内存。 - 直接内存的大小不受堆内存限制,但会受到本机内存的限制。
扩展知识
方法区和永久代的区别:
- JDK 7 及之前,HotSpot 使用永久代(PermGen)实现方法区,主要存储类信息、静态变量等。
- JDK 8 之后,永久代被移除,改为使用元空间(Metaspace),元空间使用本地内存(Native Memory)来提高性能和避免 OOM 错误。元空间可以动态调整大小,而永久代大小是固定的。
堆内存的进一步划分
- Eden 区:新对象最初会被分配到 Eden 区,且 Eden 区较大,频繁进行垃圾回收。
- Survivor 区:两个 Survivor 区 S0 和 S1 交替使用,新对象在 Eden 区经过一次垃圾回收后存放到其中一个 Survivor 区,进一步存活的对象会移动到另一个 Survivor 区,最终晋升到老年代。
- 老年代:长生命周期对象经过多次垃圾回收后会被移到老年代,Major GC 在老年代进行,频率较低但耗时较长。
虚拟机栈和栈帧
- 每当一个方法被调用时,虚拟机会在栈中创建一个新的栈帧(Stack Frame),该栈帧用于存储方法的局部变量表、操作数栈、常量池引用等。方法执行完毕后,栈帧会被弹出,释放内存。
程序计数器的作用
- 程序计数器是唯一不会出现 OOM 错误的内存区域,因为它只需要记录当前执行的字节码行号,非常小。多线程环境下,每个线程都有自己的程序计数器,以实现线程切换时的准确恢复。
最后
再来推荐下我们的面试刷题网站和小程序:面试鸭!已经有 8000+ 道面试题目啦,欢迎大家来阅读!