管中窥豹----从String Intern中观察.NET Core到.NET 8 托管堆的变迁
简介
https://www.cnblogs.com/lmy5215006/p/18494483
在此文中,研究.NET String底层结构时,我所观察到的情况与《.NET Core底层入门》,《.NET内存管理宝典》书中描述不符。故多研究了一下。发现.NET托管堆的结构也是越来越多,越来越高性能。
//示例代码
internal class Program
{
public const string constStr = "Lewis.liu";
static void Main(string[] args)
{
string name = "Lewis";
var person = Person.name;
var str = constStr;
Debugger.Break();
Console.ReadKey();
}
}
public class Person
{
public static string name = "liu";
}
.NET Core 3的托管堆结构
标准的SOH(0代,1代,2代),LOH结构,因此String Intern作为JIT编译阶段就能确定的静态内容,如果放在SOH堆中,就不太合适。存放在LOH堆中反而是更好的选择,因为LOH中没有升代,没有压缩,内存地址也不会移动。更加适合静态数据。
眼见为实----堆结构
眼见为实----是否分配在LOH
三个静态数据的内存地址
它们的GC 引用根
三个静态数据都引用了同一个gcrootGC根分配在LOH
.NET 5的托管堆结构
大家可以思考一个问题,LOH堆的定义是指>=85000byte的大对象才会进入的堆。而静态数据只是利用了LOH的特性,但本质与LOH描述不符,属于投机取巧的行为。也会给开发者带来困扰,比如说我。
因此在.NET 5 以后,CLR开发人员新增了一个Pinned object heap ,用于存储固定对象的特殊堆。来解决定义不匹配的问题
眼见为实----POH
眼见为实----是否分配在POH
.NET 8的托管堆结构
到了.NET 8 中,CLR团队又新增了NonGC heap ,顾名思义,这代表一个不会被GC的托管堆。很奇怪吧?
那有人就有疑问了? POH堆不是已经完美了吗?为什么还要新增堆?CLR团队给出了答案
主要是为了提高性能,没有写屏障,没有GC。这大大提高了效率
https://github.com/dotnet/runtime/blob/main/docs/design/features/NonGC-Heap.md
眼见为实----NonGC heap
眼见为实----是否分配在NonGC Heap
结论
因此大家在参考市面上的书籍时,切记知行合一,眼见为实。 否则用过时的知识去分享就贻笑大方啦
管中窥豹----从String Intern中观察.NET Core到.NET 8 托管堆的变迁的更多相关文章
- Java提高篇——理解String 及 String.intern() 在实际中的应用
1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ...
- Java String类中的intern()方法
今天在看一本书的时候注意到一个String的intern()方法,平常没用过,只是见过这个方法,也没去仔细看过这个方法.所以今天看了一下.个人觉得给String类中加入这个方法可能是为了提升一点点性能 ...
- 字符串常量池和String.intern()方法在jdk1.6、1.7、1.8中的变化
字符串常量池也是运行时常量池 jdk1.6中,它是在方法区中,属于“永久代” jdk1.7中,它被移除方法区,放在java堆中 jdk1.8中,取消了“永久代”,将常量池放在元空间,与堆独立了 pub ...
- 运行时常量池中的符号引用/String.intern() /ldc指令
运行时常量池,之前放在方法区(永久代)中,1.8之后被转移到元空间,放到了native memory中. 具体的数据结构是:(看对象的内存布局,句柄访问还是对象头中保存指向类的元数据的指针,这里以对象 ...
- String intern 方法 jdk中的描述
一个初始为空的字符串池,它由类 String 私有地维护. 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中 ...
- 对于JVM中方法区,永久代,元空间以及字符串常量池的迁移和string.intern方法
在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表. 在过去(当自定义类加载器使用不普 ...
- 关于jvm中的常量池和String.intern()理解
1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ne ...
- Java (JDK7)中的String常量和String.intern的实现
在java中有constantPool常量池,常量池里存放的是类,方法,接口的等常量,而对于存放字符串常量通常存放的符号链接Symbol 或者真实的String的对象的引用. 我们来看一段简单的代码和 ...
- String类中intern方法的原理分析
一,前言 昨天简单整理了JVM内存分配和String类常用方法,遇到了String中的intern()方法.本来想一并总结起来,但是intern方法还涉及到JDK版本的问题,内容也相对较多,所以今 ...
- 结合字符串常量池/String.intern()/String Table来谈一下你对java中String的理解
1.字符串常量池 每创建一个字符串常量,JVM会首先检查字符串常量池,如果字符串已经在常量池中存在,那么就返回常量池中的实例引用.如果字符串不在池中,就会实例化一个字符串放到字符串池中.常量池提高了J ...
随机推荐
- SMU Autumn 2023 Round 5
SMU Autumn 2023 Round 5 A. Everyone Loves to Sleep 把时间都转成分钟,然后存起来,二分找到离他睡觉点最近的一个时间段,减去他的睡觉点,如果最近的在第二 ...
- Ubuntu16.04使用命令行安装jdk1.8
在Ubuntu中安装jdk过于麻烦,有时设置不好可能就没有办法使用,卸载也难以卸载干净,所以这篇文章使用相对简单的命令行来安装jdk,只需简单的四个命令,省去许多麻烦,下面是方法. 进入Ubuntu打 ...
- BooleanBuilder 如何根据自定义列名 模糊查询 使用PathBuilder
// 动态传参 // 1. 声明 PathBuilder:MyTable 为类名称,"myTable" 为首字母小写后的类名 PathBuilder<MyTable> ...
- Serilog文档翻译系列(一) - 入门指南
保持优质文档是 Serilog 的优先事项.如果你发现文档中有缺失或不准确的内容,或者希望通过添加主题或教程来扩展 wiki,请通过问题追踪系统告知我们. 为什么选择Serilog? 与许多其他 .N ...
- Goby漏洞发布 | CVE-2024-4879 ServiceNowUI /login.do Jelly模板注入漏洞【已复现】
漏洞名称:ServiceNowUI /login.do Jelly模板注入漏洞(CVE-2024-4879) English Name:ServiceNowUI /login.do Input Val ...
- 技术解析 | ZEGO 移动端超分辨率技术
即构超分追求:速度更快.效果更好.码率更低.机型更广. 超分辨率(Super Resolution, SR)是从给定的低分辨率(Low Resolution, LR)图像中恢复高分辨率(High ...
- A4纸尺寸
A4纸尺寸 A4纸尺寸:210×297: A3纸尺寸:297×420: A2纸尺寸:420×594: A1纸尺寸:594×841: A0纸尺寸:841×1189: 备注:长(mm)×宽(mm) 单位: ...
- ComfyUI 基础教程(五) —— 应用 IP-Adapter 实现图像风格迁移
中秋假期,又可以玩玩 AI 了.前面介绍了 ComfyUI 的 Lora 模型以及 ControlNet,本文介绍另一个非常重要且使用的节点,IP-Adapter. 一. IP-Adapter 概念 ...
- Kubernetes DaemonSet 控制器(二十二)
通过该控制器的名称我们可以看出它的用法:Daemon,就是用来部署守护进程的,DaemonSet用于在每个 Kubernetes 节点中将守护进程的副本作为后台进程运行,说白了就是在每个节点部署一个 ...
- 【赵渝强老师】搭建Hadoop环境
说明:这里我们以本地模式和伪分布模式伪列,为大家介绍如何搭建Hadoop环境.有了这个基础,大家可以自行搭建Hadoop的全分布模式. 需要使用的安装介质: hadoop-2.7.3.tar.gz j ...