我们都知道,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. eclipse的debug模式经常自动跳到TheadPoolExecutor的断点

    1.问题:eclipse的debug模式经常自动跳到TheadPoolExecutor的断点,实在烦人 解决方法是: 在eclipse中选择Window->Preference->Java ...

  2. BZOJ4766: 文艺计算姬(Prufer序列)

    题面 传送门 题解 结,结论题? 答案就是\(n^{m-1}m^{n-1}\) 我们考虑它的\(Prufer\)序列,最后剩下的两个点肯定是一个在左边一个在右边,设左边\(n\)个点,右边\(m\)个 ...

  3. java项目迁移

    电脑重装系统以后或者从不同MyEclipse版本迁移项目时候会出现: Project facet Java 1.5 is not supported by target runtime Apache ...

  4. springboot第四篇:debug模式开发运用

    前提:项目是以maven project结构建立的,现状是无法进行断点调试的.怎么才能在eclipse里进行调试呢? 需要:①将项目打包部署到tomcat ②往项目加入dynamic web modu ...

  5. [性能测试]:ISO8583报文解析实例

    现在我们有ISO8583报文如下(十六进制表示法): 60 00 03 00 00 60 31 00 31 07 30 02 00 30 20 04 C0 20 C0 98 11 00 00 00 0 ...

  6. (转)一张图学会Dockerfile

    原文:http://blog.51cto.com/kusorz/1942816 前言 Dockerfile是非常容易学的,和SHELL相比那简单的太多了. Dockerfile是为快速构建docker ...

  7. 安装php readline扩展报错 Please reinstall libedit

    现象:configure: error: Please reinstall libedit – I cannot find readline.h解决办法:安装 Editline Library (li ...

  8. ubuntu 添加多个IP

    上次这个问题 :  UBUNTU 无法解析域名 解决方法 解决后,每次重启电脑都需要重新配置 /etc/resolv.conf. 这次添加IP的时候留心发现,在/etc/network/interfa ...

  9. HUE配置文件hue.ini 的pig模块详解(图文详解)(分HA集群和非HA集群)

    不多说,直接上干货! 一.默认的pig配置文件 ########################################################################### ...

  10. 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装Theano(图文详解)

    不多说,直接上干货! Theano的安装教程目前网上一搜很多,前几天折腾了好久,终于安装成功了Anaconda3(Python3)的Theano,嗯~发博客总结并分享下经验教训吧. 渣电脑,显卡用的是 ...