1.运行时常量池属于线程共享区中的方法区。

2.运行时常量池用于编译期生成的各种自变量,符号引用,这部分内用将在类加载后接入方法区的运行时常量池中存放。

看如下代码所示,如图:

public class Test {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc"; String s3 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
}
}

很明显s1 == s2为true,而s1 == s3为false。

因为基本数据类型和抽象数据类的引用是放在栈帧的局部变量表中。所以s1 s2是放在栈帧的局部变量表中。而“abc”这个对象则是放在运行时常量池中。

而这个常量池有钟数据结构叫Stringtable,它的数据类型可以理解为HashSet。而HashSet是无序的,不可重复的。因此第一次将定义的“abc"放入其中

而第二次定义中发现常量池中有“abc”了,则不再创建“abc"了,此时s1 和s2则引用的是同一个”abc“。因此s1 == s2为true。

而s3则是通过new出来的实例,则放进java堆中,此时s3引用的是堆中的”abc"。因此s1 == s3为false。

如果将s3变动一下又会产生什么结果呢?如下代码所示:

public class Test {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc"; String s3 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1 == s3.intern());
}
}

很明显System.out.println(s1 == s3.intern());为true。因为s3.intern()是将堆中的“abc"拿出来放进常量池中,而常量池中已经存在”abc“,因此直接把常量池中的

”abc"引用给了s3,因此System.out.println(s1 == s3.intern());为true,这就形成了运行时常量。

注意当常量池中满了同样会抛出OutOfMemory内存溢出异常。

这里顺便提提一个叫做直接内存

直接内存:并不是虚拟机运行时数据区的的一部分。当然了,这也不是虚拟机规范中定义的内存 区域。而是一种对外的内存区域。

NIO正是经常用到了对外内存。同样当对外内存满了也照样会抛出OutOfMemory内存溢出异常。抛出这种异常也要考虑一下这个区域。

JVM笔记3-java内存区域之运行时常量池的更多相关文章

  1. Java内存区域(运行时数据区域)详解、JDK1.8与JDK1.7的区别

    2.1 概述 对Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每个对象的new操作去写配对的delete/free 代码,不容易出现内存泄露和内存溢出的问题.不过,仍然需要Java虚 ...

  2. 介绍下Java内存区域(运行时数据区)

    介绍下Java内存区域(运行时数据区) Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域.JDK 1.8 和之前的版本略有不同. 下图是 JDK 1.8 对JV ...

  3. 翻译:JVM虚拟机规范1.7中的运行时常量池部分(二)

    本篇为JVM虚拟机规范1.7中的运行时常量池部分系列的第二篇. 4.4.4. The CONSTANT_Integer_info and CONSTANT_Float_info Structures ...

  4. JVM笔记(一) Java内存区域

    Java 内存区域 总概 java虚拟机在执行java程序的过程中,会把它管理的内存划分为几个不同的数据区域.每当运行一个java程序时,就会启动一个虚拟机. 具体的区域如图所示: 同时,方法区 与 ...

  5. Java内存区域(运行时数据区域)和内存模型(JMM)

    Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分. 而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之 ...

  6. 翻译:JVM虚拟机规范1.7中的运行时常量池部分(一)

    原文链接: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4 Java Virtual Machine i ...

  7. 翻译:JVM虚拟机规范1.7中的运行时常量池部分(三)

    4.4.7. The CONSTANT_Utf8_info Structure The CONSTANT_Utf8_info structure is used to represent consta ...

  8. 【搞定Jvm面试】 Java 内存区域揭秘附常见面试题解析

    本文已经收录自笔者开源的 JavaGuide: https://github.com/Snailclimb ([Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识)如果觉得不错 ...

  9. JVM探究之 —— Java内存区域

    1. 概述 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们既是拥有最高权力的“皇帝”又是从事最基础工作的“劳动人民”——既拥有每一个对象的“所有权”,又担负着每一个对象生命开始到终结的 ...

随机推荐

  1. cJSON使用

    cJSON是使用C语言编写的   关于JSON数据的   编解码库,使用方便简单 编译时注意后面要跟-lm参数,否则编译会报错 解析JSON数据包流程: 1.调用cJSON_Parse()函数,解析J ...

  2. docker基础及安装

    Docker介绍: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制 ...

  3. 小白入门Docker基础篇

    docker是什么 百科上的解释是这样的: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化 ...

  4. [DeeplearningAI笔记]ML strategy_1_3可避免误差与改善模型方法

    机器学习策略 ML strategy 觉得有用的话,欢迎一起讨论相互学习~Follow Me 1.8 为什么是人的表现 今天,机器学习算法可以与人类水平的表现性能竞争,因为它们在很多应用程序中更有生产 ...

  5. Effective Java 之-----静态工厂与构造器

    一. 考虑用静态工厂方法代替构造器: 1)静态工厂方法与构造器不同的第一大优势在于:他们有名称.当一个类需要多个带有相同签名的构造器时,就用静态方法代替构造器,并慎重的选择名称以突出他们间的区别: 2 ...

  6. java异常丢失及异常链

    1.Java中异常丢失的情况: 先定义三个异常: public class ExceptionA extends Exception { public ExceptionA(String str) { ...

  7. ES6知识点大汇总

    1 //1.搭建ES6的开发环境: 2 let a=1; 3 console.log(a); 4 //2.var 声明的是全局变量 全局变量会污染外部的区块 5 //let 局部变量 6 //cons ...

  8. BZOJ 4517: [Sdoi2016]排列计数 [容斥原理]

    4517: [Sdoi2016]排列计数 题意:多组询问,n的全排列中恰好m个不是错排的有多少个 容斥原理强行推♂倒她 $恰好m个不是错排 $ \[ =\ \ge m个不是错排 - \ge m+1个不 ...

  9. BZOJ 1434: [ZJOI2009]染色游戏

    一开始想这不$SG$裸题...然后发现100组数据...然后发现连通块是任意的求$SG$貌似要暴力枚举.... 然后想了一下1维,手动打表,每次就是队当前所有异或后缀和求$mex$,好像就是$lowb ...

  10. win2012 配置wamp的若干错误

    转自群友 VC2015.VC14 在 Windows 2012 R2 安装失败,0x80240017 - 未指定的错误,解决办法据朋友反应VC2013一样存在这个问题--查资料说是没有安装 KB299 ...