java内存模型

来源:互联网 发布:淘宝大学官网视频教程 编辑:程序博客网 时间:2024/06/07 06:50

今天我们就来聊一聊Java内存模型,面试中面试官会通过考察你对jvm的理解更深入得了解你的水平。如果你应聘的职位涉及系统调优,如堆大小的分配、垃圾回收机制的选择、处理内存溢出、线程死锁等,对JVM这一块知识就有更高的要求。

说明:因为知识点较多,扩展开来篇幅太长,jvm系列面试题将会分解开来从内存模型,垃圾回收,类加载机制,参数调优等多个角度整理,方便大家阅读。


Java 内存模型 (Java Memory Model)

JVM中用heap堆来存储运行时数据,所有类实例和数组由堆分配内存,JVM启动时创建堆(heap memory),在堆以外的内存叫非堆(non-heap memory).

jvm面试系列一:java内存模型你掌握了多少?

Java Memory Model

jvm面试系列一:java内存模型你掌握了多少?

各部分所存储的内容

下面详细了解下jvm内存模型的三个组成部分:

jvm面试系列一:java内存模型你掌握了多少?

Details

1.堆(Heap Space)

所有new出来的对象内存都分配在堆中,堆被分成年轻代(Yong Generation)和老年代(Old Generation),新生代又分成Eden和两个Survivor区。

  • Minor GC

年轻代是所有新对象产生的地方。当年轻代内存空间被用完时,就会触发垃圾回收。这个垃圾回收叫做Minor GC。年轻代被分为3个部分——Enden区和两个Survivor区。

新对象在年轻代产生,当年轻代空间占满后,会触发Minor GC开始垃圾回收,大多数新建对象位于Eden区,Eden区满后触发一次Minor GC,存活下来的对象转到survivor0区,survivor0区满后触发执行Minor GC,survivor0区存活对象全部转入survivor1区,这样保证一段时间内总有一个survivor区为空。经过多次Minor GC仍然存活的对象会转入老年代,这是由设定的年龄阈值来决定的。

  • Major GC

老年代空间存储长期存活的对象,老年代占满时会触发Major GC,花费时间较长,由于垃圾回收会导致“stop the world”事件,即所有线程都会停下来等待垃圾回收执行完成,所以对响应要求高的应用应尽量减少发生Major GC,如微博后台程序发生Major GC就会导致前台页面刷新超时,若是股票等实时交易应用发生Major GC导致响应超时,可能会给客户带来损失,这都是系统调优要考虑到的问题。

在分代收集算法中,由于年轻代中对象的存活率低,通常使用复制算法进行垃圾回收,老年代一般使用”标记-清理”或”标记-整理”算法回收存活率较高的对象。

2.永久代

永久代(Permanent Generation),用来保存程序运行时长期存活的对象,如类的元数据。

但是Java8中已经用metaspace完全替代了永久代。jvm参数-XX:PermSize 和 -XX:MaxPermSize选项会被忽略。

jvm面试系列一:java内存模型你掌握了多少?

Java8中PermGen被Metaspace替代

3.Native Area

  • PC程序计数器

程序计数器用来为线程独立拥有,线互补互补影响,保证线程切换后能准确恢复到执行位置,线程执行指令的跳转、循环、分支都要依赖计数器来完成。

  • 本地方法栈

Java栈也是线程独立的,每个线程建立一个Java栈存储数据,所以不需要关心其数据一致性,也不会存在同步锁的问题。每个Java栈存在多个栈帧(stack frame),栈帧与方法一一对应,在Hot Spot虚拟机中,使用-Xss参数来设置栈的大小,栈的大小直接决定了函数调用的可达深度。


最后结合一段代码,看看这段代码在JVM内存模型中是如何分配的:

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.logging.Logger;

/**

* Created by 嘿面试官 on 17/4/19.

*/

public class HelloWorld {

private static Logger LOGGER= Logger.getLogger(HelloWorld.class.getName());

public void sayHello(String message){

SimpleDateFormat formatter =new SimpleDateFormat("dd.MM.YYYY");

String today =formatter.format(new Date());

LOGGER.info(today+":"+message);

}

}

jvm面试系列一:java内存模型你掌握了多少?

代码对应的存储位置

0 0