我们都知道,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. order by 使用注意

    create table user ( id int primary key, name varchar(11) , depid int ); create table dept( id int pr ...

  2. Ajax请求参数解释

    ajax常用的两个请求是get和post,而springmvc的控制层可以接收ajax请求. 但是这个过程非常灵活,变化很大,容易出错. $.ajax({ url : SITE_PATH + &quo ...

  3. input disabled的情况下在IOS设备中怎么修改颜色

    -webkit-text-fill-color:black; -webkit-opacity:1; opacity: 1; 一句代码就欧了

  4. MYSQL处理高并发,防止库存超卖(图解)

    抢购场景完全靠数据库来扛,压力是非常大的,我们在最近的一次抢购活动改版中,采用了redis队列+mysql事务控制的方案,画了个简单的流程图: 先来就库存超卖的问题作描述:一般电子商务网站都会遇到如团 ...

  5. python接口自动化发送get请求 详解(一)

    前言:接口自动化实现自动化脚本比较稳定,主要用到requests模块,后面我会把这个模块单独拉出来写一下. 一.环境安装 1.用pip安装requests模块 >>pip install ...

  6. 安装vuecli和使用elememtUi

    首先需要下载node.js,这里只需要一步步的安装就可以,无需要做其他的事, 第二步:安装vue 第三步:安装脚手架 第四步: 由于国内访问npm比较慢,可以按照cnpm npm install -g ...

  7. js数字格式化为千分位

    方法1: 浏览器自带的一个方法 const num=12345.6789 num.toLocaleString();=>"12,345.679" 方法2: 正则匹配 func ...

  8. Python+USB+Vnet+FTP传输文件开发记录

    做一个Python+USB+Vnet+FTP传输文件开发记录

  9. (转)错误"因为数据库正在使用,所以无法获得对数据库的独占访问权"的解决方案

    引发原因:是因为我在还原数据库的时候,还有其他的用户正在使用数据库,所以就会出现以上提示. 解决方法:1,设置数据库在单用户模式下工作.设置方法:在需要还原的数据库上右击,在右键菜单命令上选择&quo ...

  10. 12.Proxy

    1.概述 Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程. Proxy 可以理解成,在目标对象之前架 ...