JVM的内存分配及各种常量池的区别(静态常量池、运行时常量池、字符串常量池)

这篇具有很好参考价值的文章主要介绍了JVM的内存分配及各种常量池的区别(静态常量池、运行时常量池、字符串常量池)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JVM内存分配

先了解下JVM中的内存分配,此处以hotspot vm为例(官方jdk采用的vm)

程序计数器

1. 虚拟机栈

2. 本地方法栈

Java堆

堆内存是各个线程共享的区域

方法区

它用于存储已经被虚拟机加载的类信息、常量、静态变量、即编译器编译后的代码等数据。静态变量、常量在方法区,所有方法,包括静态和非静态的,也在方法区

这里解释一下方法区:

  • 首先方法区不是在堆中,在java8之前是用永久代实现的,永久代Hotspot 虚拟机特有的概念,虽然 Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来

  • java8之后是用元空间实现的,元空间并不在虚拟机中,而是使用本地内存。

只是 JVM 规范中定义的一个概念,用于存储被 JVM 加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

 文章来源地址https://www.toymoban.com/news/detail-413135.html

常量池

常量池分为静态常量池运行时常量池

1. 静态常量池

也叫 class文件常量池,主要存放编译期生成的各种字面量(Literal)和符号引用(Symbolic References)

final类型的常量在编译期间就会进行分配。

静态常量池指的是在编译期确定,保存在class文件中的一些数据。

静态常量池是在编译期间生成的,存储在.class文件中。

 

字面量(Literal)和符号引用量,字面量相当于Java语言层面常量的概念,如文本字符串、声明为final的常量值等,符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:

  • 1、类和接口的全限定名;

  • 2、字段的名称和描述符;

  • 3、方法的名称和描述符。

2. 运行时常量池

  • 当类加载到内存中后,JVM就会将class常量池中的内容存放到运行时常量池中;运行时常量池里面存储的主要是编译期间生成的字面量、符号引用等等。

  • 类加载在链接环节的解析过程,会符号引用转换成直接引用(静态链接)。此处得到的直接引用也是放到运行时常量池中的。

  • 运行期间可以动态放入新的常量

运行时常量池内存位置:java8之前都在方法区中,java8之后在元空间

2.1 字符串常量池

字符串常量池,也可以理解成运行时常量池分出来的一部分。类加载到内存的时候,字符串会存到字符串常量池里面。利用池的概念,避免大量频繁创建字符串

  • JDK6时字符串常量池位于运行时常量池,JDK7挪到堆中。

Hotspot8之前,使用持久代实现方法区,由于持久代内存不好估算,很容易到值OOM:Perm Gen异常。而元空间是本地内存,取决于操作系统分配内存。

字符串常量池位置变迁

Jdk1.6及之前: 有永久代, 运行时常量池在永久代,运行时常量池包含字符串常量池

Jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池从永久代里的运行时常量池分离到堆里

Jdk1.8及之后: 无永久代,运行时常量池在元空间,字符串常量池里依然在堆里

 

 

参考文章

(62条消息) 深入理解java虚拟机(全章节完整)_TJtulong的博客-CSDN博客

(62条消息) Java | JVM | 详细图解,坚持看完,带你真正搞懂Java虚拟机_唐 城的博客-CSDN博客

(62条消息) Java-双亲委派机制_七楼、的博客-CSDN博客

(62条消息) Java-类加载器11127222七楼、的博客-CSDN博客

(62条消息) jvm中的常量池到底在哪里?常量池在哪里yuan_qh的博客-CSDN博客

(62条消息) Java方法区和永久代java永久代和方法区yuan_qh的博客-CSDN博客

这一次,彻底弄懂java中的常量池 - 掘金 (juejin.cn)

(62条消息) JAVA常量池,一篇文章就足够入门了。(含图解)lei'chang'liang'chi河海哥yyds的博客-CSDN博客

(62条消息) Java 常量池详解(一)字符串常量池_new hilbert()的博客-CSDN博客

彻底搞清楚class常量池、运行时常量池、字符串常量池 - Awecoder - 博客园 (cnblogs.com)

 

 

到了这里,关于JVM的内存分配及各种常量池的区别(静态常量池、运行时常量池、字符串常量池)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C/C++】静态内存分配与动态内存分配

    1.1 - 定义概述 内存分配 (Memory Allocation) 是指为计算机程序或服务分配物理内存空间或虚拟内存空间的一个过程。通常在程序执行前或执行时完成内存分配。 1.2 - 分类概述 存在两种类型的内存分配: 编译时内存分配或静态内存分配 (Compile-time or Static Memory Allocation) 运行时内存

    2024年02月11日
    浏览(40)
  • Jvm创建对象之内存分配-JVM(七)

    上篇文章介绍了jvm创建,会校验是否已加载类,没有则加载,通过之前学的源码,classLoader加载完之后,虚拟机开始给类分配内存,指针移动分配和free链表分配,解决并发分配情况用cap和TLAB方法。之后设置对象头部信息,有mark word线程锁,分代年龄等,klass pointer。还有指针

    2024年02月13日
    浏览(68)
  • JVM 给对象分配内存空间

    指针碰撞 空闲列表 TLAB 为对象分配空间的任务实际上便等同于把一块确定大小的内存块从Java堆中划分出来。 指针碰撞:(Bump The Pointer) 堆的内存是绝对规整的,内存主要分为两部分,所有使用过的内存被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点

    2024年02月11日
    浏览(36)
  • JVM的故事—— 内存分配策略

    堆内存有新生代和老年代,新生代中有一个Eden区和一个Survivor区(from space或者to space)。当有新的对象分配时,会优先分配在Eden区。当Eden区空间不足分配给新对象时,会进行一次minor GC,回收完没有引用的对象后,先考虑把一些Eden区的对象放到Survivor区,如果放不下,就放到老

    2024年02月10日
    浏览(36)
  • jvm对象创建和内存分配优化

    1、类加载检测 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。 new指令对应语言层面讲是,new、对

    2024年02月13日
    浏览(56)
  • JVM面试题-JVM对象的创建过程、内存分配、内存布局、访问定位等问题详解

    内存分配的两种方式 指针碰撞 适用场合:堆内存 规整 (即没有内存碎片)的情况下。 原理:用过的内存全部整合到一边,没有用过的内存放在另一边,中间有一个分界指针,只需要向着没用过的内存方向将该指针移动对象内存大小位置即可。 使用该分配方式的GC收集器:

    2024年02月08日
    浏览(49)
  • JVM—对象的创建流程与内存分配

    对象创建的流程图如下: 内存分配的方式有两种: 指针碰撞(Bump the Pointer) 空闲列表(Free List) 分配方式 说明 收集器 指针碰撞(Bump the Pointer) 内存地址是连续的(新生代) Serial和ParNew收集器 空闲列表(Free List) 内存地址不连续(老年代) CMS收集器和Mark-Sweep收集器

    2024年04月10日
    浏览(48)
  • JVM运行时数据区——字符串常量池位置的调整

            在JDK6及之前,使用永久代来实现方法区,字符串常量池(StringTable)是在 永久代(方法区)中 的,但是方法区的回收效率不高,在Full GC时才会回收。           在JDK7中,将字符串常量池 转移到了堆中 ,分配在年轻代和老年代中。         在JDK8中,为了 融合

    2024年02月16日
    浏览(32)
  • JVM对象创建与内存分配机制深度剖析

    (1)类加载检查 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程; 所以所类加载是 懒加载 ; new指令对应到语

    2024年02月13日
    浏览(48)
  • JVM对象在堆内存中是否如何分配?

    1:指针碰撞:内存规整的情况下 2:空闲列表: 内存不规整的情况下 选择那种分配方式 是有 java堆是否规整而决定的。而java堆是否规整是否对应的垃圾回收器是否带有空间压缩整理的能力决定的。 因此当使用Serial,ParNew等带有压缩整理过程的收集器时,系统采用的分配算法是

    2024年02月16日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包