一.虚拟机的构成

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

而我们所说的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. mysql8.0安装时,Unable to connect to any of the specified MySQL hosts

    https://blog.csdn.net/u014776759/article/details/88422967

  2. JVM Server与Client运行模式

    JVM Server模式与client模式启动,最主要的差别在于:-Server模式启动时,速度较慢,但是一旦运行起来后,性能将会有很大的提升.原因是: 当虚拟机运行在-client模式的时候,使用的 ...

  3. Django-07-Model操作

    一.数据库的配置 1. 数据库支持 django默认支持sqlite.mysql.oracle.postgresql数据库  <1> sqlite django默认使用sqlite的数据库 ...

  4. 【LEETCODE】69、动态规划,easy,medium级别,题目:198、139、221

    package y2019.Algorithm.dynamicprogramming.easy; /** * @ProjectName: cutter-point * @Package: y2019. ...

  5. 【leetcode-62,63,64 动态规划】 不同路径,最小路径和

    给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [   [1,3,1], [1,5,1] ...

  6. txt文件每行内容与图片文件名字组合,输出txt格式

    import os dir_list = os.listdir('C:\\Users\\10107472\\Desktop\\practice\\JPEGImages')i=0f1=open('C:\ ...

  7. 2019 浪潮java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.浪潮等公司offer,岗位是Java后端开发,因为发展原因最终选择去了浪潮,入职一年时间了,之前面试了很多家公 ...

  8. Java之路---Day08

    2019-10-22-22:28:39 目录 1.Static静态类 2.Static内存图 3.Static静态代码块 4.Arrays类 5.Math类 Static静态类 一旦使用static修 ...

  9. LRU(Least Recently Used)算法的理解

    https://blog.csdn.net/wydyd110/article/details/84023688 感谢 ,自己学习记笔记 内存里建立一个哈希表,后来数据多了,爆了.咋整呢? 一个算法,就 ...

  10. Flutter Platform Channels

    Flutter Platform Channels(一) https://www.jianshu.com/p/33ac774f99b1 https://www.jianshu.com/p/c1e206 ...