一.虚拟机的构成

虚拟结主要由运行时数据区、执行引擎、类加载器三者构成:

而我们所说的JVM内存模型指的就是运行时数据区,下面具体分析一下运行时数据区:

二.运行时数据区组成和各个区域的作用

我们看到运行时数据区可以分为线程共享和线程不共享两部分,其中堆内存和方法区线程共享,本地方法栈、虚拟机栈、程序计数器线程不共享。

接下来我们介绍每一个区域的作用:

2.1.程序计数器

程序计数器(Program Counter Register),也有称作为PC寄存器。想必学过汇编语言的朋友对程序计数器这个概念并不陌生,在汇编语言中,程序计数器是指CPU中的寄存器,它保存的是程序当前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址),当CPU需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。

2.2虚拟机栈

虚拟机栈也叫java栈,栈中存储的是帧栈,每一个方法对应一个帧栈,方法执行完毕后进行弹栈,让出栈内存,帧栈中存储着方法中定义的变量,如果是基本数据类型,就在栈中进行值的存储,如果是引用数据类型,存储的是引用指向对象的地址。

虚拟机栈也叫栈内存,是在线程创建时创建,它的生命期是跟随线程的生命,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束,该栈就 Over,所以不存在垃圾回收。也有一些资料翻译成JAVA方法栈,大概是因为它所描述的是java方法执行的内存模型,每个方法执行的同时创建帧栈(Strack Frame)用于存储局部变量表(包含了对应的方法参数和局部变量),操作栈(Operand Stack,记录出栈、入栈的操作),动态链接、方法出口等信息,每个方法被调用直到执行完毕的过程,对应这帧栈在虚拟机栈的入栈和出栈的过程。

局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象的引用(reference类型,不等同于对象本身,根据不同的虚拟机实现,可能是一个指向对象起始地址的引用指针,也可能是一个代表对象的句柄或者其他与对象相关的位置)和 returnAdress类型(指向下一条字节码指令的地址)。局部变量表所需的内存空间在编译期间完成分配,在方法在运行之前,该局部变量表所需要的内存空间是固定的,运行期间也不会改变。

2.3本地方法栈

和虚拟机栈功能相似,不过本地方法栈存储针对本地方法。

2.4堆内存

堆内存主要用来存储被创建的对象,一个类new出一个对象,会在堆中开辟内存空间,并在栈中存储一个引用,存储着对象在堆中的地址。堆内存中的对象存储着自己的成员变量,并不保存对象的方法,方法被保存在帧栈中,堆内存也称为gc堆,是主要用来进行垃圾回收的内存。

2.5方法区

方法区是一个非常重要的区域,也是被线程共享的区域,方法区存储了每个类的信息(类的名称、方法信息、字段信息),静态变量、常量以及编译后的代码等。

方法区还包括一个常量池,用来存储编译期间生成的字面量和符号引用。这部分内容在类被加载后,都会存储到方法区中的RCP。值得注意的是,运行时产生的新常量也可以被放入常量池中,比如 String 类中的 intern() 方法产生的常量。

常量池就是这个类型用到的常量的一个有序集合。包括直接常量(基本类型,String)对其他类型、方法、字段的符号引用.

三.常量池的使用

3.1什么是常量?

常量是指被final修饰的变量,值一旦确定就无法改变。

final可以修饰静态变量、实例变量和局部变量。

3.2Clss文件中的常量池

我们知道方法区中存放着class文件的信息,还包括用来存储class常量的常量池,方法区中还存在运行时常量池两者什么关系?

常量池主要用来存放两大类常量:字面量和符号引用量,字面量相当于Java语言的常量,如文本字符串,声明为final的常量等,符号引用包括以下三种

类和接口的全限定名

字段名称和描述符

方法名称和描述符

3.3方法区中的运行常量池

class文件中的常量池中的内容会在类加载后进入方法区的运行时常量池。相对于常量池,运行时常量池的重要特征是具有动态性,java并不要求常量只有在编译器才会产生,运行期间也可以将新的常量存放入池中,这种特性用的最多的String类中的intern()方法。

3.4常量池的作用和==号的意义

常量池是为了避免频繁的创建和销毁对象造成系统性能的浪费,实现了对象的共享。

==号比较基本数据类型,就是比值,比较引用数据类型比较的是内存中存放的地址。

3.2常量池的应用

对于byte、short、long、char、boolean对应的包装器类都有对应的常量池,这五种包装器类默认创建在-128到127的对象会存放在在缓存中。

对于两种浮点数没有实现常量池技术。

3.4String类和常量池

String str1="abc";
String str2=new String("abc");
System.out.println(str1==str2);

结果为false;

深入理解JVM内存分配和常量池的更多相关文章

  1. 深入理解JVM内存分配策略

    理解JVM内存分配策略 三大原则+担保机制 JVM分配内存机制有三大原则和担保机制 具体如下所示: 优先分配到eden区 大对象,直接进入到老年代 长期存活的对象分配到老年代 空间分配担保 对象优先在 ...

  2. JVM内存分配及String常用方法

    一,JVM内存分配和常量池 ​ 在介绍String类之前,先来简单分析一下在JVM中,对内存的使用是如何进行分配的.如下图所示(注意:在jdk1.8之后便没有方法区了): ​ ​ 如上JVM将内存分为 ...

  3. JVM 内存分配模型概念和java中各种对象的存储

    JVM 内存分配模型概念 --在工作中可能用到的机会不多,有个概念的了解 --此文是转载某位读者,应该是在阅读了<深入理解Java虚拟机JVM高级特性与最佳实践> 一书后,总结所得.写的不 ...

  4. 走进JVM【二】理解JVM内存区域

    引言 对于C++程序员,内存分配与回收的处理一直是令人头疼的问题.Java由于自身的自动内存管理机制,使得管理内存变得非常轻松,不容易出现内存泄漏,溢出的问题. 不容易不代表不会出现问题,一旦内存泄漏 ...

  5. 第二章 JVM内存分配

    注意:本篇博客,主要参考自以下四本书 <分布式Java应用:基础与实践> <深入理解Java虚拟机(第二版)> <突破程序员基本功的16课> <实战java虚 ...

  6. Android性能调优篇之探索JVM内存分配

    开篇废话 今天我们一起来学习JVM的内存分配,主要目的是为我们Android内存优化打下基础. 一直在想以什么样的方式来呈现这个知识点才能让我们易于理解,最终决定使用方法为:图解+源代码分析. 欢迎访 ...

  7. java虚拟(一)--java内存区域和常量池概念

    一.java运行时数据区 也可以称为java内存区域,和java内存模型不是一回事,不要弄混,这里基于jdk1.8之前 1.1.方法区 线程共享,类装载过程中产生的java.lang.Class对象保 ...

  8. 你应该这样理解JVM内存管理

    在进行Java程序设计时,一般不涉及内存的分配和内存回收的相关代码,此处引用一句话: Java和C++之间存在一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外的人想进去,墙里面的人想出来 ,个人从这 ...

  9. Java内存中的常量池

    1,java内存模型简介 <深入理解java虚拟机>里将java内存分为如下五个模块: 堆-堆是所有线程共享的,主要用来存储对象. 其中,堆可分为:新生代和老年代两块区域.使用NewRat ...

随机推荐

  1. pvs显示unknown device

    一 .不要unknown的那块pv盘的解决办法 [root@gezi ~]# pvs WARNING: Device for PV D1LLfT-3Hle-NbrP-5165-Q6WR-2UWF-2x ...

  2. 袁新生《LINGO和Excel在数学建模中的应用》

    内容介绍 本书深入浅出地介绍了LINGO的基础知识.用LINGO语言描述现实问题的方法和用Excel处理数据的方法,重点是这两种软件在解决各种优化问题以及在数学建模中的应用,通过丰富的实例介绍了把实际 ...

  3. LuoguP2698 【[USACO12MAR]花盆Flowerpot】

    题目描述 首先我们简化一下题意: 要找一段区间[L,R],使区间[L,R]内元素最大值减最小值大于等于D. 做法: 首先很容易想到采用二分,分什么呢? 我们二分区间长度为mid 这个时候,检验就成为了 ...

  4. 洛谷--P1028 数的计算(递推)

    题意:链接:https://www.luogu.org/problem/P1028 先输入一个自然数n (n≤1000) , 然后对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自 ...

  5. Delphi百度文字识别【支持通用文字识别、身份证识别、银行卡识别、驾驶证识别、行驶证识别、车牌识别等功能】

    作者QQ:(648437169) 点击下载➨Delphi百度文字识别          百度api文档 [Delphi百度文字识别]支持 通用文字识别.通用文字识别(高精度版).通用文字识别(含位置信 ...

  6. cloudera cdh6.3 离线安装 经典大数据平台视频教程(含网盘下载地址)

    cdh6.3企业级大数据视频教程 链接:https://pan.baidu.com/s/1bLGrIwzpFQB-pQRb6KOmNg 提取码:i8h8 系统和软件版本1,操作系统:Centos7.6 ...

  7. 记一次node爬虫经历,手把手教你爬虫

    今天业务突然来了个爬虫业务,爬出来的数据以Excel的形式导出,下班前一个小时开始做,加班一个小时就做好了.因为太久没做爬虫了!做这个需求都是很兴奋! 需求说明 访问网站 (循环)获取页面指定数据源 ...

  8. 分布式缓存重建并发冲突和zookeeper分布式锁解决方案

    如果缓存服务在本地的ehcache中都读取不到数据. 这个时候就意味着,需要重新到源头的服务中去拉去数据,拉取到数据之后,赶紧先给nginx的请求返回,同时将数据写入ehcache和redis中 分布 ...

  9. 阿里巴巴 Java 开发手册 (八) 注释规约

    1. [强制]类.类属性.类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用 //xxx 方式. 说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Ja ...

  10. python class 中__next__用法

    class A(): def __init__(self,b): self.b=b # def __iter__(self): # 这个函数可以用,表示迭代标志,但也可以省略 # return sel ...