我们都知道,java程序的跨平台性离不开java虚拟机,虚拟机隔绝了底层操作系统,使得java程序可以直接运行在虚拟机之上。所以,对java的学习,离不开对java虚拟机的学习与了解。下面简单整理下java虚拟机的内存模型,用于备忘,加深理解。

一、java虚拟机的模型

  话不多说,先上张内存模型图吧:

百度来的图,大概也描述清楚了我们常用的虚拟机的内存模型了,主要分为两大类:线程共享(相当于所有线程都可以访问,如果是单线程程序则对应所有方法都能访问)和线程私有(属于某个线程的数据域),其实我们刚刚接触java的时候,会笼统地将内存分为堆内存和栈内存,前者对应的便是线程共享区,后者对应的便是线程私有区。

二、各个区域存放的数据

  1、方法区:存放静态变量、类相关信息(可以理解为class对象的数据和相关方法字节码等)以及字符串等常量。方法区中有一个常量池,它专门存放常用的常量,包括常见的字符串常量。总而言之,这个区域存放的是和类相关的数据。

  2、堆:存放各种方法(包括new操作符,反射,clone,反序列等)创建的对象的数据,和方法区相比较:它是存放对象相关的数据。

  3、虚拟机栈:存放运行时对应线程的所有方法的数据(当然,根据方法的调用顺序以栈的形式存储,后面详细讲),通俗地将,就是存放该线程运行时的一些方法局部变量,这个其实就是初学者所说的栈区域了。

  这里重点补充下方法栈和栈帧的概念:方法之间的调用关系是通过栈来实现的,而每个栈帧代表的是每个方法的对应栈地址,大概画个图说明下:

该示意图对应一下的代码执行块:

//测试类
class Test implements Runnable{
//方法A
public void methodA(){
System.out.println("A方法");
}
//方法B
public void methodB(){
System.out.println("B方法,我调用了A方法");
methodA();
}
//方法C
public void methodC(){
System.out.println("C方法,我调用了B方法");
methodB();
}
public void run() {
//线程执行入口
Test t = new Test();
t.methodC();
} }

代码和示意图大概的意思是:

  A、早调用的方法位于栈的下端,最后调用的方法位于栈的顶端。

  B、方法栈其实就是方法的执行路径,越先调用,越后执行;

  C、栈帧其实就是存储了当前方法的对应栈中的地址值,在每个方法执行完,它都会改变(其实就是栈顶地址)。

  4、程序计数器区域:每个线程运行其实就是通过方法之间的调用进行,而程序计数器就是控制方法调用的代码,该区域存放对应程序计数器执行相关的数据,一般包括当前执行的方法信息以及下一步执行的方法的信息。

  5、本地方法区:本地方法相对于java程序而言的,它不是java程序,一般是java虚拟机运行所需要的一些方法。

三、虚拟机内存与对象的创建和访问

  1、对象的创建

  每个新对象的产生,都会涉及到所有的内存区域(native先不考虑),具体看下面丑图,它具体地展示了一个新对象产生时内存中发生了什么事情:

    

上面的示意图大概说明了对象产生过程内存中发生了什么事情,然后,线程中的虚拟机栈中的方法如何访问堆中的对象?

  2、对象的访问方式:直接引用访问和句柄访问。

  A、直接引用指向堆内存地址的方式。该方式是方法中的对象引用直接指向对象地址,这样做的好处是访问速度快,节省空间(相对于下面的方法而言);但是它在对象进行空间移动后(一般进行垃圾回收时会发生对象的内存位置改变的情况),需要修改所有应用的地址,这样会损失一定的性能;

  B、通过句柄访问对象。该方法相对于直接引用指向对象的方法而言,它在引用和对象之间多了一个句柄,这个句柄存储有对应某个对象的内存地址,当某个引用变量想访问对象时,只需通过该句柄访问即可。该方法会降低引用访问对对象的速度,同时相对于上面的引用直接访问方法也增加了一定的存储空间性能开销,但是在对象进行地址表更时,只需要修改句柄的地址即可。

java虚拟机的大概模型总结到这里,其实总的来说内容也不多,但是弄懂了虚拟机的内存布局的确对于我们理解java程序挺有帮助的。后面将会简单总结下垃圾回收的相关知识点。

java虚拟机的内存机制的更多相关文章

  1. 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制

    一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...

  2. Java虚拟机:内存模型详解

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实 ...

  3. JVM学习001通过实例总结Java虚拟机的运行机制

    JVM学习(1)——通过实例总结Java虚拟机的运行机制-转载http://www.cnblogs.com/kubixuesheng/p/5199200.html 文章转载自:http://www.c ...

  4. java 虚拟机的类加载机制

    Java 虚拟机的类加载机制 关于类加载机制: ​ 虚拟机把描述类的数据从Class 文件加载到内存,并对数据进行效验.转换解析和初始化,最终 形成可以被虚拟机直接使用的Java 类型,就是虚拟机的类 ...

  5. java虚拟机的内存模型

    一.为什么要了解java虚拟机的内存模型 java虚拟机作为java代码运行的平台,是java技术的基石.了解java虚拟机的内存模型也就变得十分必要.它能帮助我们更好的了解java代码的运行机制,更 ...

  6. Java虚拟机的内存管理

    众所周知,Java程序员写的代码是没有办法控制Java对象的内存释放的,完全有JVM暗箱操作. 虽然程序员把内存的释放的任务都交给了Java虚拟机,但是并不代表Java程序就不存在内存泄漏. 反而,某 ...

  7. 1 - JVM随笔分类(java虚拟机的内存区域分配(一个不断记录和推翻以及再记录的一个过程))

    java虚拟机的内存区域分配   在JVM运行时,类加载器ClassLoader在加载到类的字节码后,交由jvm的执行引擎处理, 执行过程中需要空间来存储数据(类似于Cpu及主存),此时的这段空间的分 ...

  8. Java虚拟机之内存区域

    原创文章,转载请标明出处! 目录 一.背景 二.运行时内存区域概述 1.官方描述 2.中文翻译 3.内存区域简述 4.运行时数据区简图 5.运行时数据区详图 三.JVM线程 JVM数据区域与线程关系 ...

  9. 【进阶之路】深入理解Java虚拟机的类加载机制(长文)

    我们在参加面试的时候,经常被问到一些关于类加载机制的问题,也都会在面试之前准备的时候背好答案,但是我们是否有去深入了解什么是类加载机制呢?这段时间因为一些事情在家看了些书,这次就和大家分享一些关于Ja ...

随机推荐

  1. 2018-2019-2 20165219《网络对抗技术》Exp4 恶意代码分析

    基础问题回答 实验目的 监控系统的运行状态,看有没有可疑的程序在运行 分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,systracer套 ...

  2. “全栈2019”Java异常第十七章:Error详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  3. junit所需要的jar包

    hamcrest-core-1.1.jar junit-4.12.jar http://central.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/ ...

  4. P5277 【模板】多项式开根(加强版)(bsgs or Cipolla)

    题面 传送门 题解 首先你得会多项式开根->这里 其次你得会解形如 \[x^2\equiv a \pmod{p}\] 的方程 这里有两种方法,一个是\(bsgs\)(这里),还有一种是\(Cip ...

  5. PHP消息队列实现

    一个经典的消息队列就是这样的,主要是入队出队操作. shell脚本日志输出 学习地址:http://www.imooc.com/article/19111

  6. RHEL配置本地yum

    RHEL(即Red Hat Enterprise Linux的缩写)配置本地yum 提前将 rhel-server-6.7-x86_64-dvd.iso 文件上传到服务器上 1.在根目录创建文件夹/m ...

  7. mysql随机取出若干条记录的实用方法

    1.常见的方法 ; 这种方法可以随机取得数据,但是如果表比较大,数据量很多的时候会很耗时. 2.优化后的方式 ) as t ); 分析,首先根据条件筛选出要选的数据,然后随机排序取出要的条数的id , ...

  8. BiliBili, ACFun… And More!【递归算法】

    题源:http://acm.uestc.edu.cn/#/problem/show/3 题解: 题意:播放一段视频文件,有播放速度和缓冲速度两种,因为作者的癖好,播放前要缓冲几秒钟(这段时间不计算在总 ...

  9. Flutter视图基础简介--Widget、Element、RenderObject

    前言:Flutter官方文档里的一句话:you build your UI out of widgets(使用Flutter开发UI界面时,都是使用Widget),然而,Widget并不是我们真正看到 ...

  10. 使用NHibernate(4)--拦截器和事件

    如果想在一个事务的开始.执行中.完成后等过程中执行一些自己的逻辑(比如记录日志.查看sql),拦截器(Interceptors)和事件(Event)就可以发挥作用了.两者所能完成的功能差不多. 1,拦 ...