Java面试准备之JVM详细研究一(Java内存区域)

Object obj = new Object();

主要参考资料:《深入理解Java虚拟机》,未经本人及原书作者同意禁止转载。

JVM中的数据区域

JVM中给数据分了这么几个区域:

其中:

  1.程序计数器:

    程序计数器是一块较小的内存空间,为当前线程所执行的字节码的行号指示器。也就是说,程序再翻译成为字节码了之后,分支、循环、跳转、异常处理、线程恢复等功能都需要程序计数器来完成。

    (注意!)此区域存储的东西是执行的虚拟机的字节码指令的地址,如果为natvie方法(natvie:一个调用非Java语言的代码时的关键字),则存储为空。

    (特别的)此区域是JVM中唯一一个没有规定任何OutOfMemoryError(内存溢出错误)的区域

  2.Java虚拟机栈

    此区域描述的是方法执行的内存模型,每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作栈、动态链接方法出口等信息。

    每一个方法调用的过程就是一个栈帧在虚拟机栈中入栈和出栈的过程

       局部变量表:存放编译器可知的各种基本数据类型(八种:Boolean\byte\char\short\int\long\float\double)、对象引用类型和returnAddress类型(指明一条字节码指令的地址)。

    这个区域中有两种异常情况:  StackOverflowError异常(栈深度大于虚拟机所允许的深度时触发)

                   OutOfMemoryError异常(这当然,除了程序计数器区都会有)

  3.本地方法栈

    注意名字:native method stack,跟Java中的关键字native是一样的,意思就是这个区跟虚拟机栈差不多,不过它是为本地方法(也就是native修饰的部分)工作的。

    异常抛出和虚拟机站一样。 

  4.Java堆

    虽然图中看起来很小,但是它却是JVM管理的内存中最大的一块,被所有线程所共享;

    这个区唯一的作用是存放对象实例,几乎所有的对象实例都在堆上分配(可以类比基本数据类型,他们就是在虚拟机栈中分配的)。Java虚拟机规范中规定:所有的对象实例以及数组坐标都要在堆上分配。理解这一部分对我们在程序中的内存分配有一个大体的印象。

    Java堆还是垃圾收集器管理的主要区域,一次有一个别名叫“GC堆”,这一部分内容会在以后的文章中讨论。

    此外,Java堆是可以再物理上不连续的,当此区域内存不够时,会抛出OutOfMemoryError异常。

  5.方法区

    作用是存储已经被虚拟机加载的类信息、常量、静态变量等数据。

  6.运行时常量池

    根据名字理解,就是存放常量的地方,位于方法区。一般在编译时候就会确定程序的常量

    这个部分对于理解String很有帮助:

      一般情况下,我们使用一个双引号“”就可以创建一个常量并存储在常量池中,因此:

      

String s1 = "Java";
String s2 = "Java";
//s1 == s2为TRUE

      当是创建一个String对象的时候,这个对象并不位于堆中,而是位于常量池中;s2继续同样的语句的时候,其回先在常量池中寻找一样Unicode编码的字符串,如果有就不再进行创建。以上代码共创建了1个对象。

    此区域同样会出现OutOfMemoryError异常。

      但是,如果使用new的方法创建了一个字符串,也就是在堆中创建了两个相同内容的字符串对象的时候,就会输出不一样的结果:

String s1 = new String("Java");
String s2 = new String("Java");
//s1 == s2为FALSE

      因为使用new操作符进行对象创建的时候,因为括号中的内容(即构造方法的参数完全可能不确定),因此以上代码创建出来了两个内容相同,但是引用地址却不同的对象。

对象访问:

  一个简单的Java语句:

Object obj = new Object();

  它牵扯到了JVM中的多少地方呢?

  首先程序计数器的使用肯定是少不了的,如果没有程序计数器,这个语句在哪里JVM都不会知道;其次,Object obj这部分将会反应刀虚拟机栈中的本地变量表里面,作为一个reference的类型数据出现;而new   Object() 这部分则是在堆中进行了内存的分配;在对象实例中,又会包含许多对象类型数据的地址信息,这些存储在方法区中,其他线程可以访问。

  在这里,我们讨论的对象访问在JVM中有两种实现方式,一种是通过句柄访问对象,如图:

  

  一种是通过直接指针访问对象。在我们使用的虚拟机(Sun HotSpot而言),是通过直接地址访问的:

  

(内存区域介绍完)

Java面试准备之JVM详细研究一(Java内存区域)

时间: 2024-12-16 02:01:36

Java面试准备之JVM详细研究一(Java内存区域)的相关文章

Java面试准备之JVM详细研究三(类加载机制)

类加载过程 一个类从编写完成后,编译为字节码之后,它要装载进内存有七个阶段: 加载 => (验证-> 准备-> 解析)=> 初始化=> 使用=> 卸载 括号中的三个步骤可以整合成为 “连接”步骤.其中的步骤并不是一个阶段结束,一个阶段才开始的.只是说他们的开始阶段基本遵循此顺序(解析阶段更是可能在使用的时候才发生,目的是配合动态绑定),这些阶段都是互相交叉的混合式进行的,通常会在一个阶段执行过程中调用或激活另一个阶段. 1.加载 ”加载“的过程是”类加载“过程的一个阶段

关于Java面试知识点解析——JVM基础篇

跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己的发展,偏移自己规划的轨迹),还是钱给少了,不受重视. 准备不充分的面试,完全是浪费时间,更是对自己的不负责(如果title很高,当我没说).今天给大家分享下 Java面试知识点解析--JVM基础篇 1)Java 是如何实现跨平台的? 注意:跨平台的是 Java 程序,而不是 JVM.JVM 是用 C/C++ 开发的,是

Java面试准备之JVM

介绍JVM中7个区域,然后把每个区域可能造成内存的溢出的情况说明 程序计数器:看做当前线程所执行的字节码行号指示器.是线程私有的内存,且唯一一块不报OutOfMemoryError异常. Java虚拟机栈:用于描述java方法的内存模型:每个方法被执行时都会同时创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息.每一个方法被调用直至执行完成的过程就对应着一个栈帧在虚拟机中从入栈到出栈的过程.如果线程请求的栈深度大于虚拟机所允许的深度就报StackOverflowError, 如果

JVM系列一:虚拟机内存区域

虚拟机栈 1.虚拟机栈维护一个线程中所有方法的栈帧,每个栈帧中保存着这个方法中用到的局部变量表,操作数栈,常量引用 2.可以用-Xss来设置每个线程中虚拟机栈的大小,在jdk1.4之前默认虚拟机栈大小是256K,在jdk1.5+默认虚拟机栈大小是1M java -Xss2M HackTheJava 3.该区域可能抛出的异常 当线程请求的栈深度超过最大限制后,或抛出StackOverflowError 当栈进行动态扩展无法申请到内存后,会抛出OutOfMemoryError 本地方法栈 本地方法栈

jvm系列(八):jvm知识点总览-高级Java工程师面试必备

在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来取胜了,但是练到高手之后,内功就更主要了.一个内功低的人招式在奇妙也打不过一个内功高的人.比如,你剑法再厉害,一剑刺过来,别人一掌打断你的剑,你还怎么使剑法,你一掌打到一个武功高的人身上,那人没什么事,却把你震伤了,你还怎么打.同样两者也是相辅相成的,内功深厚之后,原来普通的一招一式威力也会倍增. 对于搞开发的我们其实也是

【搞定Jvm面试】 Java 内存区域揭秘附常见面试题解析

本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb ([Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识)如果觉得不错的还,不妨去点个Star,鼓励一下! Java 内存区域详解 如果没有特殊说明,都是针对的是 HotSpot 虚拟机. 写在前面 (常见面试题) 基本问题 介绍下 Java 内存区域(运行时数据区) Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么) 对象的访问定位的两种

转:最近5年133个Java面试问题列表

最近5年133个Java面试问题列表 Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入. 在我初入职场的时候,类似于 Vector 与 Array 的区别.HashMap 与 Hashtable 的区别是最流行的问题,只需要记住它们,就能在面试中获得更好的机会,但这种情形已经不复存在.如今,你将会被问到许多 Java 程序员都没有看过的领域,如 NIO,

Java面试宝典

http://www.cnblogs.com/bluestorm/p/6429894.html Java面试宝典 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用).主要有以下优点: 可替换性:多态对已存在代码具有可替换性. 可扩充性:增加新的子类不影响已经存在的类结构. 接口性:多态是超累通过方法签名,想子类提供一个公共接口,由子类来完善或

学习jvm(一)--java内存区域

前言 通过学习深入理解java虚拟机的教程,以及自己在网上的查询的资料,做一个对jvm学习过程中的小总结. 本文章内容首先讲解java的内存分布区域,之后讲内存的分配原则以及内存的监控工具.再下来会着重讲解垃圾回收这一章节,该章节涉及了垃圾的标记算法以及各种垃圾回收算法,然后大概的介绍下市面上使用的垃圾收集器.之后就总结下上面的原理,讲解相关的jvm调优案例.然后会着重讲解类加载过程.最后一章讲字节码的部分,字节码相对来说是比较枯燥而且特别繁琐的内容,最好是自己动手配合着学习会好一点,或者观其大