转载:  https://blog.csdn.net/a745233700/article/details/80291694  (虽然大部分内容都其实是深入理解jvm虚拟机这本书里的,不过整理的很牛逼)

一 java运行时内存中的数据区域

每一个Java程序启动后,会获得一个JVM的实例,用来管理内存。Java 虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有个字的用途,以及创建和销毁时间。Java虚拟机所管理的内存将会包括以下几个运行时数据区域:

1、程序计数器:程序计数器是一块较小的空间,是当前线程执行的字节码的行号指示器,字节码解释器工作时,就是通过改变计数器的值来选取下一条需要执行的字节码指令。(线程私有,每个线程都有一个独立的程序计数器,互不影响,独立存储)

2、Java虚拟机栈:线程私有,生命周期与线程的生命周期相同。它描述java方法执行的内存模型,每个方法执行的时候都会创建一个栈帧,以帧的形式存放本地方法的调用状态,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用到执行完成,就对应着一个栈帧在虚拟机中入栈到出栈的过程。

3、本地方法栈:本地方法栈的作用和虚拟机栈的作用非常相似,区别是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。

4、Java堆:占用内存最大的区域,在虚拟机启动时创建,用于存放对象实例,可以划分为新生代和老年代。

5、方法区:用于存储被虚拟机加载的类信息,常量,静态变量,即使编译器编译后的代码等数据。

二 内存分配:

首先将class文件加载到方法区(存放类的基本信息,静态变量,编译后的代码等信息),然后new一个类,为这个类在Java堆中分配内存(主要是给字段属性分配内存)。调用一个方法时,根据方法的引用在方法区找到对应方法,然后在Java虚拟机栈中分配一个栈帧给这个方法存储相关信息。

1、new对象创建的过程:

(1)首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用;

(2)检查这个符号引用代表的类是否已被加载、解析和初始化;

(3)如果没有,那必须先执行相应的类加载过程;

(4)如果有,虚拟机将为新生对象分配内存,并使用CAS保证操作原子性,分配方式有:指针碰撞和空闲列表;

(5)虚拟机将分配到的内存空间都初始化为零值,这一步保证了对象的实例字段在Java代码中可以不赋初始值就可以直接使用;

(6)对对象进行必要的设置;

(7)执行<init>方法,把对象按照程序员意愿进行初始化。

2、分配方式:

(1)指针碰撞:如果java堆是绝对规整的,所有用过的内存都放在一边,所有没用过的内存存放在另一边,中间存放一个指针作为分界点指示器。分配内存时,将指针从用过的内存区域向空闲内存区域移动等距离区域。

(2)空闲列表:如果java不是规整的,这时,虚拟机就必须维护一张列表,列表上记录了可用的内存块,在分配内存时,从列表上找到一个足够大的连续内存块分配给对象,并更新列表上的记录。

3、对象的内存布局:

在HotSpot中,对象的内存布局分成三部分:对象头,实例数据,对齐填充。

(1)对象头:包括两部分的信息:

第一部分用于存储对象自身的运行时数据,如哈希码,GC代年龄,锁状态标志等。

第二部分是对象指向它的类元数据的类元指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。如果对象是一个Java数组,那对象头中还必须有一块用于记录数组长度的数据。

(2)实例数据:是对象真正存储的有效信息,是在程序代码中所定义的各种类型的字段内容,相同宽度的字段会被分配到一起。

(3)对齐填充:并不是必然存在的,仅起着占位符的作用。

4、对象的访问定位:

Java程序通过栈上的reference数据来操作堆上的具体对象。目前访问对象主要有两种方式:通过句柄访问对象和直接指针访问对象。

(1)通过句柄访问对象:

(2)通过直接指针访问对象:

(3)优劣对比:

① 使用句柄,reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要修改。

②直接指针,速度快,节省一次指定定位的开销。

转载: Java虚拟机:运行时内存数据区域、对象内存分配与访问的更多相关文章

  1. 读书笔记:深入理解java虚拟机(一)虚拟机的运行时的数据区域

    最近在看深入了解java虚拟机第一版(周志明著),特此写读书笔记,整理其中重要的东西和自己的理解. ”java与c++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却 ...

  2. java虚拟机学习笔记(五)---运行时的数据区域

    Java虚拟机所管理的内存包括以下几个运行时的数据区域:方法区,堆,虚拟机栈,本地方法栈,程序计数器.下面对其进行介绍: 程序计数器 它是一块较小的内存空间,可以看做当前线程做执行的字节码的信号指示器 ...

  3. 关于Java虚拟机运行时数据区域的总结

    Java虚拟机运行时数据区域 程序计数器(Program Counter) 程序计数器作为一个概念模型,这个是用来指示下一条需要执行的字节码指令在哪. Java的多线程实际上是通过线程轮转做到的,如果 ...

  4. 《深入理解Java虚拟机》(二)Java虚拟机运行时数据区

    Java虚拟机运行时数据区 详解 2.1 概述 本文参考的是周志明的 <深入理解Java虚拟机>第二章 ,为了整理思路,简单记录一下,方便后期查阅. 2.2 运行时数据区域 Java虚拟机 ...

  5. Java虚拟机运行时数据区

    运行时数据区程序计数器Java虚拟机栈本地方法栈Java堆(GC堆)方法区运行时常量池 运行时数据区 Java虚拟机在运行Java程序时,会将它所管理的内存划分为若干个内存区域.这些数据区域有各自的用 ...

  6. 面试常问的 Java 虚拟机运行时数据区

    写在前面 本文描述的有关于 JVM 的运行时数据区是基于 HotSpot 虚拟机. 概述 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以 ...

  7. Java 虚拟机运行时数据区

    写在前面 本文描述的有关于 JVM 的运行时数据区是基于 HotSpot 虚拟机. 概述 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以 ...

  8. 【深入理解Java虚拟机】Java虚拟机运行时数据区

    Java虚拟机运行时数据区 线程私有 程序计数器 1.当前线程所执行的字节码的行号指示器. 2.唯一不会发生OutOfMemoryError的区域 3.如果执行的是java方法,计数器值为虚拟机字节码 ...

  9. Java虚拟机运行时栈帧结构--《深入理解Java虚拟机》学习笔记及个人理解(二)

    Java虚拟机运行时栈帧结构(周志明书上P237页) 栈帧是什么? 栈帧是一种数据结构,用于虚拟机进行方法的调用和执行. 栈帧是虚拟机栈的栈元素,也就是入栈和出栈的一个单元. 2018.1.2更新(在 ...

  10. Java虚拟机-运行时数据区域

    Java虚拟机管理的内存包括如图所示的运行时数据区域: 下面分别进行介绍: 1)程序计数器(Program Counter Register) 占用的内存空间比较小,主要作用就是标识当前线程执行的字节 ...

随机推荐

  1. 基于DDD的微服务设计和开发实战

    你是否还在为微服务应该拆多小而争论不休?到底如何才能设计出收放自如的微服务?怎样才能保证业务领域模型与代码模型的一致性?或许本文能帮你找到答案. 本文是基于 DDD 的微服务设计和开发实战篇,通过借鉴 ...

  2. mysql中information_schema.triggers字段说明

    1. 获取所有触发器信息(TRIGGERS) SELECT  *  FROM information_schema.TRIGGERS WHERE  TRIGGER_SCHEMA='数据库名';  TR ...

  3. CodeForces 796D

    不能一个一个bfs,要一起bfs #include<iostream> #include<vector> #include<cstdio> #include< ...

  4. JVM系列(二):JVM的内存模型

    深入理解JVM内存模型    Java虚拟机在执行Java程序的过程中,把它所管理里的内存划分了不同的数据类型区域,作为一名开发者,我们需要了解jvm的内存分配机制以及这些不同的数据区域各自的作用. ...

  5. centos6.x将python2.6升级到2.7

    一,安装开发工具和Python2.7(1)查看当前python版本 python -V Python 2.6.6 (2)下载Python-2.7.3 wget http://python.org/ft ...

  6. 通过公网连接阿里云redis,rinetd

    目前云数据库 Redis 需要通过 ECS 的内网进行连接访问.如果您本地需要通过公网访问云数据库 Redis,可以在 ECS Linux 云服务器中安装 rinetd 进行转发实现. 1.在云服务器 ...

  7. 洛谷$P4322\ [JSOI2016]$最佳团体 二分+$dp$

    正解:二分+$dp$ 解题报告: 传送门$QwQ$ 这题长得好套路嗷,,,就一看就看出来是个$01$分数规划+树形$dp$嘛$QwQ$. 考虑现在二分的值为$mid$,若$mid\leq as$,则有 ...

  8. Java入门(三)——集合概讲

    集合(或者叫容器)是Java的核心知识点,它有着很深的深度.我们这里不会设计多深,仅仅作为了解入门,深入了解请移步各种集合源码文章.好的,下面正是开始介绍... Java集合为何而生 我们知道,Jav ...

  9. BridgePattern(桥接模式)-----Java/.Net

    桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化.这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦

  10. 1033 旧键盘打字 (20 分)C语言

    题目描述 旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及坏掉的那些键,打出的结果文字会是怎样? 输入描述: 输入在2行中分别给出坏掉的那些键.以及应 ...