JVM内存简析

JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)

堆区:
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身
栈区:
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
为了更清楚地搞明白发生在运行时数据区里的黑幕,我们来准备2个小道具(2个非常简单的小程序)。

AppMain.java
public class AppMain                
//运行时, jvm 把appmain的信息都放入方法区
{
public   static   void  main(String[] args)  //main 方法本身放入方法区。
{
Sample test1 = new  Sample( " 测试1 " );   //test1是引用,所以放到栈区里, Sample是自定义对象应该放到堆里面
Sample test2 = new  Sample( " 测试2 " );
test1.printName();
test2.printName();
}
} 
Sample.java
public class Sample //运行时, jvm 把appmain的信息都放入方法区 { /** 范例名称 */ private name; //new Sample实例后, name 引用放入栈区里, name 对象放入堆里 /** 构造方法 */ public Sample(String name) { this .name = name; } /** 输出 */ public void printName() //print方法本身放入 方法区里。 { System.out.println(name); } }

系统收到了我们发出的指令,启动了一个Java虚拟机进程,这个进程首先从classpath中找到AppMain.class文件,读取这个文件中的二进制数据,然后把Appmain类的类信息存放到运行时数据区的方法区中。这一过程称为AppMain类的加载过程。
接着,Java虚拟机定位到方法区中AppMain类的Main()方法的字节码,开始执行它的指令。这个main()方法的第一条语句就是:
Sample test1=new Sample("测试1");
语句很简单啦,就是让java虚拟机创建一个Sample实例,并且呢,使引用变量test1引用这个实例。貌似小case一桩哦,就让我们来跟踪一下Java虚拟机,看看它究竟是怎么来执行这个任务的:
1、 Java虚拟机一看,不就是建立一个Sample实例吗,简单,于是就直奔方法区而去,先找到Sample类的类型信息再说。这会儿的方法区里还没有Sample类呢。可Java虚拟机也不是一根筋的笨蛋,于是,它发扬“自己动手,丰衣足食”的作风,立马加载了Sample类,把Sample类的类型信息存放在方法区里。
2、 好啦,资料找到了,下面就开始干活啦。Java虚拟机做的第一件事情就是在堆区中为一个新的Sample实例分配内存, 这个Sample实例持有着指向方法区的Sample类的类型信息的引用。这里所说的引用,实际上指的是Sample类的类型信息在方法区中的内存地址,其实,就是有点类似于C语言里的指针啦~~,而这个地址呢,就存放了在Sample实例的数据区里。
3、 在JAVA虚拟机进程中,每个线程都会拥有一个方法调用栈,用来跟踪线程运行中一系列的方法调用过程,栈中的每一个元素就被称为栈帧,每当线程调用一个方法的时候就会向方法栈压入一个新帧。这里的帧用来存储方法的参数、局部变量和运算过程中的临时数据。OK,原理讲完了,就让我们来继续我们的跟踪行动!位于“=”前的Test1是一个在main()方法中定义的变量,可见,它是一个局部变量,因此,它被会添加到了执行main()方法的主线程的JAVA方法调用栈中。而“=”将把这个test1变量指向堆区中的Sample实例,也就是说,它持有指向Sample实例的引用。
OK,到这里为止呢,JAVA虚拟机就完成了这个简单语句的执行任务。参考我们的行动向导图,我们终于初步摸清了JAVA虚拟机的一点点底细了,COOL!
接下来,JAVA虚拟机将继续执行后续指令,在堆区里继续创建另一个Sample实例,然后依次执行它们的printName()方法。当JAVA虚拟机执行test1.printName()方法时,JAVA虚拟机根据局部变量test1持有的引用,定位到堆区中的Sample实例,再根据Sample实例持有的引用,定位到方法去中Sample类的类型信息,从而获得printName()方法的字节码,接着执行printName()方法包含的指令。

 

转载于:https://www.cnblogs.com/lwhctv/p/10180813.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/570023.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos下离线安装mysql

卸载原有冲突的依赖包 rpm -e postfix rpm -e mariadb-libs 按顺序安装 rpm -ivh mysql-community-common-5.7.27-1.el7.x86_64.rpm rpm -ivh mysql-community-libs-5.7.27-1.el7.x86_64.rpm rpm -ivh mysql-community-client-5.7.27-1.el7.x86_64.rpm rpm -ivh mysql-com…

记一次es和mq的netty冲突

1.今天在服务里面加了 es 6.4的 依赖包后,在预发布测试时候出现了下列的问题 看了 半天,最后发现是 es的 jar包 和 mq的 netty包 有冲突。然后去idea的 jar包依赖里面查看,mq使用的 是 而es依赖的netty 是多个 不同的包, 而在依赖…

Windows平台下搭建自己的Git服务器

Gitblit 是一个纯 Java 库用来管理、查看和处理 Git 资料库,相当于 Git 的 Java 管理工具。 Gitblit 支持Linux操作系统,因此 Gitblit 需要java运行环境(JRE)。 如果公司要搭建自己的 Git 服务器,可以使用 Gitblit 这个…

Python 基本数据类型 (二) - 字符串

str.expandtabs([tabsize]): str类型的expandtabs函数,有一个可选参数tabsize(制表符大小)详细来说,expandtabs的意思就是,将字符串中的制表符\t,全部用空格来替换。至于用多少个空格,需要参考制…

如何预防后台被攻击?Tomcat 的安全配置来啦!

安全是系统架构中最重要的关注点之一,通常情况下,所说的安全涵盖网络安全、数据安全、操作系统安全、服务器安全以及应用系统安全等诸多方面。Tomcat 是一个免费的开放源代码 的Web应用服务器,技术先进、性能稳定。由于它优秀的稳定性以及丰富…

Spring Boot 单例模式中依赖注入问题

在日常项目开发中,单例模式可以说是最常用到的设计模式,项目也常常在单例模式中需要使用 Service 逻辑层的方法来实现某些功能。通常可能会使用 Resource 或者 Autowired 来自动注入实例,然而这种方法在单例模式中却会出现 NullPointExceptio…

VO,BO,PO,DO,DTO的区别

面对这个图,让我们先从承上启下的DTO开始入手 DTO(Data Transfer Object)数据传输对象 这个传输通常指的前后端之间的传输 DTO是一个比较特殊的对象,他有两种存在形式: 在后端,他的存在形式是java对象&…

Windows下pip 离线包安装

pip在线安装十分方便,有时候某些服务器并没有直接联网,需要下载好安装包上传到服务器上进行安装,不经常用,还是有点小麻烦的。 安装Python之后,将下载好的安装包包放在Python安装的根目录下使用pip install packagenam…

VMware设置及linux静态ip设置

1. VMWARE虚拟机NAT模式上网设置 1.1. VM虚拟机设置 1.1.1. 虚拟机全局设置 启动虚拟机选择【虚拟网络编辑器】 如果需要管理员权限点【更改设置】,没有提示这忽略这一步 选择NAT模式,更改下面的子网IP,改成你需要的任何一个子网网段&…

问题 L: 超超的中等意思

问题 L: 超超的中等意思 时间限制: 1 Sec 内存限制: 128 MB提交: 366 解决: 27[提交] [状态] [命题人:jsu_admin]题目描述 已知p,q,k和一个难搞得多项式(pxqy)^k。想知道在给定a和b的值下计算多项式展开后x^a*y^b得系数s。输入 多组输入,每组数据一行输入p,q,k,a,…

SELinux 引起的 Docker 启动失败

问题描述 Linux OS 版本 CentOS Linux release 7.2.1511 (Core) 启动Docker service docker start 启动失败信息 原因分析 Error starting daemon: SELinux is not supported with the overlay2 graph driver on this kernel. Either boot into a newer kernel or disabl...nab…

postgresql模糊匹配正则表达式性能问题

postgresql 模糊匹配 目前建议使用like,~~,不建议使用正则表达式, 目前有性能问题https://yq.aliyun.com/articles/405097正则表达式效率比较低下:操作符 ~~ 等效于 LIKE, 而 ~~* 对应 ILIKE。 还有 !~~ 和 !~~* 操作符 分别代表 …

配置MySQL的环境变量

配置MySQL的环境变量 1.现在安装MySQL ——–下载最新版MySQL软件,将MySQL安装到系统目录中,记录当前安装目录; 如安装mysql到D:\wamp\mysql目录下 2.打开win7系统——右击计算机——单击属性-弹出win7系统页面 3.高级系统设置-环境变…

通过mysqldump备份数据库

使用mysqldump命令备份 mysqldump命令的作用是备份MySQL数据库。是将数据库中的数据备份成一个文本文件。表的结构和表中的数据将存储在生成的文本文件中。mysqldump命令的工作原理很简单。它先查出需要备份的表的结构,再在文本文件中生成一个CREATE语句。然后&…

ThinkPHP-保存生成的二维码

通过TP框架引入Qrcode插件,然后调用插件生成二维码,并保存1.引入qrcode插件: 2.功能页面-生成二维码按钮: 3.生成二维码-代码: 4.后台代码-通过vendor方法引入: //下载生成的二维码-引用方法1 pu…

工厂方法 Factory Method

背景:有一个应用框架,它可以向用户显示多个文档。在这个框架中,两个主要的抽象是类Application和Document.这两个类都是抽象的。客户必须通过它们的子类来做与举替应用相关的实现。 分析:因为被实例化的特定Document子类是与特定应…

解析.DBC文件, 读懂CAN通信矩阵,实现车内信号仿真

通常我们拿到某个ECU的通信矩阵数据库文件,.dbc后缀名的文件。 直接使用CANdb Editor打开,可以很直观的读懂信号矩阵的信息,例如下图: 现在要把上图呈现的信号从.dbc文件中解析出来,供实现自动化仿真总线信号使用&…

01-数据库基础

1 数据库系统概述 1.1 数据库的4个基本概念 数据(Data):数据库中存储的基本对象数据库(Database):长期储存在计算机内、有组织的、可共享的大量数据的集合。数据库管理系统(DBMS):用户与操作系统之间的一层…

linux命令——crontab的使用方法

一、crond简介 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检…

第一个程序 快速编译链接的办法

转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/10223249.html