博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CLR的简单理解
阅读量:4034 次
发布时间:2019-05-24

本文共 994 字,大约阅读时间需要 3 分钟。

        CLR加载程序生成进程,一个进程中可以存在多个线程,当创建一个线程时,会分配1Mb的空间,也就是线程的栈空间,对应jvm的虚拟机堆栈,是线程执行过程中用到的工作内存。这片内存用于方法传递实参,并存储方法内部定义的局部变量,栈是从高位地址向低位地址构建。栈是由操作系统直接管理,不受GC控制,当执行的方法退出后,栈中的存储会自动释放。栈的效率很高,但存储空间有限。

        对象的数据存储在堆上,堆上的数据是所有线程共享的,堆根据类型又分为:GC堆、加载堆(Loader Heap)、大对象(LOH)堆。当对象实例大小小于85000字节时,该对象会被分配到GC堆上,GC回收主要是回收这一片区域,回收过后会进行压缩。当对象实例大小大于85000个字节时,会被分配到LOH堆,只有GC进行完全回收时这片区域的数据才会被回收,且回收后不会压缩。

        加载堆(Loader Heap)用来存储类型的元数据,也就是类的Type信息,反射的时候就是用到这里面的信息。每个类在加载堆中对应一个方法表(Method Table),里面记录该类的元数据信息,比如基类型、静态字段、继承的接口、所有的方法等。加载堆不受GC控制,不会被回收,其生命周期是从创建(第一次使用)直到AppDomain卸载。

        当我们在程序中new一个对象时,会根据这个对象的大小(字段数据等)在GC堆中生成这个对象的内存空间,其中字段数据直接在这个对象空间中,同时这个对象会包含两个引用:TypeHandle和SyncBlockIndex。其中TypeHandle指向加载堆(Loader Heap)中的方法表(Method Table),SyncBlockIndex指针指向Synchronization Block的内存块,用于在多线程环境下对实例对象的同步操作。当这些都准备好以后,会将GC堆中的内存地址返回给栈中该变量,这里也是整个new的过程。

        这里有必要对加载堆(Loader Heap)做下补充,其实在类第一次使用(不一定是new)的时候,类的元数据信息就会被放到加载堆(Loader Heap)中。当真正new一个对象的时候,其实加载堆(Loader Heap)中已经有该类的元数据信息,如果没有,也会先创建。然后再将这个对象的TypeHandle和加载堆中的该类型的MethodTable对应起来。

        以上所有描述,可参考下图:

 

转载地址:http://xrzdi.baihongyu.com/

你可能感兴趣的文章
一文看清HBase的使用场景
查看>>
除了负载均衡,Nginx还可以做很多,限流、缓存、黑白名单
查看>>
解析zookeeper的工作流程
查看>>
搞定Java面试中的数据结构问题
查看>>
CentOS7 安装 MySQL8
查看>>
springcloud中fegin第一次跨模块调用超时
查看>>
scratch win10 环境搭建
查看>>
谷歌浏览器安装 elasticsearch-head 插件
查看>>
Oracle 字符串批量替换
查看>>
Flink 使用 Scala 编程中注意的隐式转换
查看>>
Flink SQL 开发的代码结构
查看>>
Flink SQL 项目通用模板一
查看>>
Flink 连接 MySQL 错误:The server time zone value ‘Öйú±ê׼ʱ¼ä‘ is unrecognized or represents
查看>>
大数据集群巡检,最佳实践记录
查看>>
纯JS实现QQ右下角弹窗demo
查看>>
JS页面一键分享QQ空间、新浪微博、豆瓣等小工具
查看>>
jQuery实现的进度条效果
查看>>
jQuery常用小技巧
查看>>
【Spring官方指南学习】Spring构建一个 restful web service
查看>>
java中native的用法
查看>>