首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
您找到你想要的搜索结果了吗?
是的
没有找到

.NET面试题系列 - C# 基础知识(1)

如果问法是考定义,比如问“类型与引用类型有何区别?” 这种问题答案一查都找得到,也没有什么意义。较好问法是,把概念问题融入到情景之中,或者构造一个连环问题。...如果发现栈或者堆上空间不足,就引发OutOfMemory异常,并激发一次垃圾回收。 如果是引用类型,堆上分配第一步算出来字节数。 初始化”类型对象指针“和”同步块索引“。...这个新对象将会被初始化,Joe将作为其初始化信息一部分(不再是默认,例如0或者Null)。 注意此时第一个Manager对象将会变成垃圾,等待垃圾回收器回收。...静态构造函数不应该调用基类型静态构造函数。这是因为类型不可能有静态字段是基类型分享或继承。 如果我们不了解堆上内存分配方式,对静态构造函数理解十分困难。为什么是在创建第一个实例之前?...因为类型对象只需要建立一次,所以这个静态构造函数也只能运行一次。 为什么静态构造函数既没有访问修饰符,也没有参数?

1.8K20

听GPT 讲Go源代码--mbitmap.go

在这个过程中,堆上存储对象标记信息需要被写入到相应位图中,以便在垃圾回收过程中能够通过快速地访问位图来确定哪些对象是可达,哪些对象是可以清除。...在垃圾回收过程中,需要根据这些位图来确定哪些对象需要被回收,并将其堆上释放。...如果布尔为true,则将对象标记为活动对象;如果布尔为false,则将对象标记为未活动对象。在垃圾回收器扫描阶段,遍历所有的对象并标记它们。被标记为活动对象对象将不会被清除。...接下来,函数检查heapBits缓存数组(bh.ptrbits),如果该地址所在堆页heapBits已经被缓存了,则直接返回该堆页heapBits指针;否则,重新mheap中分配一个heapBits...堆位图是Go语言运行时系统中一种数据结构,用于记录堆中哪些内存块被分配,哪些没有被分配。在堆上分配内存时,Go运行时系统空闲内存中分配一块可用内存块,然后将其标记成已分配状态,同时更新堆位图。

18020

深入理解屏障技术

垃圾回收范围 程序中使用到内存分为两种,分为堆内存和栈内存。垃圾回收是堆内存,不含栈内存。函数调用和返回,函数及局部变量占用内存自动释放。...也就是说栈中数据可以通过简单编译器指令自动清理,所以不需要专门进行垃圾回收。 为什么垃圾回收 在什么是垃圾回收中也说了进行垃圾回收目的是对内存进行重复使用。...如何判断一个对象是否可达,第一步找出所有的全局变量和当前函数栈中变量,将其标记为可达;第二步,已经标记数据开始,进一步标记它们可访问变量,依次类推,知道没有可标记对象为止,则剩下未标记对象即为不可达对象...无论全局还是栈不可能能访问到这些对象,可以安全清理。 Go1.5三色并发标记垃圾回收 在Go1.5版本中,使用了三色标记算法。...下面对对象操作所有情况进行一个分析,得到如下矩阵 如上图所示,一共有8种情况,可以看到插入屏障+删除屏障结合能够搞定堆上各种对象操作,也就是说混合写屏障能够搞定堆上所有的情况。那栈上怎么办呢?

80920

CLR和.Net对象生存周期

引用类型总是托管堆分配,每次我们通过使用new操作符返回对象内存地址——即指向对象数据内存地址,而后把这个内存地址pop进线程栈中。...Tips:进程初始化时,CLR自动划出一个地址空间区域作为托管堆(相对于本机堆说法,是由一个由CLR访问随即内存块)。每个托管进程都有一个托管堆,进程中所有线程都在同一堆上分配对象记忆。...CLR要求所有对象(主要指引用类型)都用new操作符创建,new操作符在完成四步操作以后,返回指向托管堆上新建对象一个引用(或指针,视情况而定),在使用完以后,C#并没有如C++对应delete操作符来删除对象...2.1 为什么需要垃圾回收 我们始终要明确一个概念,为什么我们需要垃圾回收——这是因为我们运行环境内存总是有限。当CLR在托管堆上为非垃圾对象分配地址空间时,总是分配出新地址空间,且呈连续分配。...具体流程如下: GC准备阶段 在这个阶段,CLR暂停进程中所有线程,这是为了防止线程在CLR检查根期间访问堆。 GC标记阶段 当GC开始运行时,它会假设托管堆上所有对象都是垃圾

79060

CLR和.Net对象生存周期

引用类型总是托管堆分配,每次我们通过使用new操作符返回对象内存地址——即指向对象数据内存地址,而后把这个内存地址pop进线程栈中。...Tips:进程初始化时,CLR自动划出一个地址空间区域作为托管堆(相对于本机堆说法,是由一个由CLR访问随即内存块)。每个托管进程都有一个托管堆,进程中所有线程都在同一堆上分配对象记忆。...CLR要求所有对象(主要指引用类型)都用new操作符创建,new操作符在完成四步操作以后,返回指向托管堆上新建对象一个引用(或指针,视情况而定),在使用完以后,C#并没有如C++对应delete操作符来删除对象...2.1 为什么需要垃圾回收 我们始终要明确一个概念,为什么我们需要垃圾回收——这是因为我们运行环境内存总是有限。当CLR在托管堆上为非垃圾对象分配地址空间时,总是分配出新地址空间,且呈连续分配。...具体流程如下: GC准备阶段 在这个阶段,CLR暂停进程中所有线程,这是为了防止线程在CLR检查根期间访问堆。 GC标记阶段 当GC开始运行时,它会假设托管堆上所有对象都是垃圾

1.1K50

内存逃逸

但是在Go语言中,我们并不需要非常关心一个对象到底是申请在栈上还是堆上,因为Go编译器确定对象真正分配位置,如果一个变量或对象需要分配在堆上时,自动将其分配在堆上而不是栈上,使用new创建对象也不一定是分配在堆上...如果子程序分配了一个对象返回一个指向它指针,则可以根据返回指针来访问对象,这时对象不能直接存放在栈上。...如果将变量分配在堆上,堆不会像堆栈一样自动清理。导致Go频繁做垃圾回收,垃圾回收会占用大量系统开销。 堆与栈相比,堆适用于不可预测大小内存分配。但是这样做代价是分配速度慢,形成内存碎片。...通过escapeDemo2_1和escapeDemo2_2可以看到,64K是一个临界,小于64K会分配在栈上,大于等于64K对象会分配到堆上。...下面的几种情况必然发生逃逸 函数内部创建变量,在函数返回返回变量指针 变量指针被赋值给一个已经逃逸变量某个字段 元素为*T类型slice、Map和chan 在堆上分配内存比在栈上静态分配内存开销要大不少

27120

.NET基础面试题整理

垃圾回收器处理是引用对象,而且只回收堆上内存。这意味着假如维持对一个对象引用,就会阻止GC重用对象使用内存。在.NET中,垃圾回收器采用是mark-and-compact算法。...这样一来,垃圾回收器就可以识别所有可达对象,在执行回收时候,GC不是枚举所有访问不到对象,相反,通过压缩所有相邻可达对象来执行垃圾回收。不可访问对象就会被覆盖。...类型与引用类型 结构是类型:类型在栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,通过使用结构可以创建更多类型 类是引用类型:引用类型在堆上分配地址堆栈执行效率要比堆执行效率高...而堆则需要GC(Garbage collection:垃圾收集器)清理 07 7.什么情况下会在堆(栈)上分配数据?它们有性能上区别吗?“结构”对象可能分配在堆上吗?...,返回是泛型 010 10.异常作用是什么?.

1.5K21

Java内存大家都知道,但你知道要怎么管理Java内存吗?

它不能访问其它局部变量,因为这些变量超出了作用域。一旦方法完成并返回,堆栈顶部就会溢出,活跃作用域也会发生变化。...当有一个强引用指向堆上对象时,或者通过一系列强引用可以强访问对象,则该对象不会被作为垃圾回收。 2. 弱引用>> 简单来说,在下一个垃圾回收进程之后,对堆中对象弱引用很可能不会继续存在了。...因此,你可以保留对它弱引用,万一垃圾回收器运行,它可能破坏堆中对象。因此,过了一会儿,如果你想要检索你引用对象,你可能突然得到一个空返回。...虚引用>>> 用于算法检查后清理操作,因为我们知道有些对象不需要再存在。仅与引用队列一起使用,因为此类引用.get()方法将始终返回。这些引用类型被认为是优于终结器。...比方说,所有红色对象都符合被垃圾回收器条件。 你可能注意到堆上有一个对象,它对同一堆上其它对象进行了强引用(例如,可能是引用了自己项列表,或者是具有两个引用类型字段对象)。

82820

Golang之变量去哪儿

虽然也有new函数,但是使用new函数得到内存不一定就在堆上。堆和栈区别对程序员“模糊化”了,当然这一切都是Go编译器在背后帮我们完成。...这些局部变量是在栈上分配(静态内存分配),一旦函数执行完毕,变量占据内存会被销毁,任何对这个返回动作(如解引用),都将扰乱程序运行,甚至导致程序直接崩溃。...因为变量是在堆上创建,所以函数退出时不会被销毁。但是,这样就行了吗?new出来对象该在何时何地delete呢?...调用者可能忘记delete或者直接拿返回传给其他函数,之后就再也不能delete它了,也就是发生了内存泄露。关于这个坑,大家可以去看看《Effective C++》条款21,讲得非常好!...通过逃逸分析,可以尽量把那些不需要分配到堆上变量直接分配到栈上,堆上变量少了,减轻分配堆内存开销,同时也减少gc压力,提高程序运行速度。

74320

Golang之变量去哪儿

虽然也有new函数,但是使用new函数得到内存不一定就在堆上。堆和栈区别对程序员“模糊化”了,当然这一切都是Go编译器在背后帮我们完成。...这些局部变量是在栈上分配(静态内存分配),一旦函数执行完毕,变量占据内存会被销毁,任何对这个返回动作(如解引用),都将扰乱程序运行,甚至导致程序直接崩溃。...因为变量是在堆上创建,所以函数退出时不会被销毁。但是,这样就行了吗?new出来对象该在何时何地delete呢?...调用者可能忘记delete或者直接拿返回传给其他函数,之后就再也不能delete它了,也就是发生了内存泄露。关于这个坑,大家可以去看看《Effective C++》条款21,讲得非常好!...通过逃逸分析,可以尽量把那些不需要分配到堆上变量直接分配到栈上,堆上变量少了,减轻分配堆内存开销,同时也减少gc压力,提高程序运行速度。

50320

.NET基础拾遗(1)类型语法基础和内存管理基础

(1)装箱:CLR需要做额外工作把堆栈上类型移动到堆上,这个操作就被称为装箱。   (2)拆箱:装箱操作反操作,把堆中对象复制到堆栈中,并且返回。 ?   ...第1代,经历过一次垃圾回收后,依然保留在堆上对象。     第2代,经历过两次或以上垃圾回收后,依然保留在堆上对象。...根据.NET垃圾回收机制,0代、1代和2代初始分配空间分别为256KB、2M和10M。说完分代垃圾回收设计,也许我们会有疑问,为什么要这样弄?...垃圾回收时,GC所有仍在被使用根引用出发遍历所有的对象实例,那些不能被遍历到对象将被视为不再被使用而进行回收。...试想一个不断尝试访问离线数据库Finalize方法,将会在长时间内不会返回,这不仅影响了对象释放,也使得排在Finalize方法队列中所有后续对象得不到释放,这个连锁反应将会导致很快地造成内存耗尽

59920

JVM(2): 逃逸分析和内存分配

首先来说下为什么会有逃逸分析 我们都知道Java对象都是分配在在堆上,在过往认识中,一直是以这样方式存在,但是Java7开始支持对象栈分配和逃逸分析机制。...线程逃逸:有可能被外部线程访问到,譬如赋值给类变量或可以在其他线程中访问实例变量。 主要涉及三种场景,分别是全局变量赋值、方法返回、实例引用传递。...3.矢量替代,逃逸分析如果发现对象内存存储结构不需要连续进行的话,就可以将对象部分甚至全部都保存在CPU寄存器内 下面我们来说下对象内存分配 为对象分配空间任务等同于把一块确定大小内存Java...,列表中找出一块分配给划分给对象实例,并更新列表上记录。...TLAB 线程本地分配缓冲区(Thread Local Allocation Buffer),由于Java对象一般分配在堆上,在有多个线程需要在堆上申请空间时,那么需要对这些对象申请进行同步,在有多个对象进行申请时

57110

C++ 为什么不加入垃圾回收机制

结论是,原则上和可行性上说,垃圾回收都是需要。但是对今天用户以及普遍使用和硬件而言,我们还无法承受将C++语义和它基本库定义在垃圾回收系统之上负担。”...temp,它和val共享同一份数据,并修改了实际,函数返回后,val拥有的同样也发生了变化,而实际上val本身并没有修改过。...然后调用了foo2(val),函数中使用了一个无名临时对象创建了一个新,使用赋值表达式修改了val,同时val和临时对象拥有同一个,函数返回时,val仍然拥有这正确。...然而,多态性仍然没有解决,我将在另一篇文章专门介绍使用容器管理多态对象问题。 语言支持 为什么不在C++语言中增加对垃圾回收支持?...根据前面的讨论,我们可以看见,不同应用环境,也许需要不同垃圾回收器,不管三七二十一使用垃圾回收,需要将这些不同类型垃圾回收器整合在一起,即使可以成功(对此我感到怀疑),也导致效率成本增加。

76530

Android内存分配与回收

想写一篇关于android内存分配和回收文章想法来源于追查一个魅族手机图片滑动卡顿问题,我们想了很多办法还是没有避免他不停GC,所以就打算详细看看内存分配和GC原理,为什么不断GC...Growth Limit:是系统给每一个程序最大堆上限,超过这个上限,程序就会OOM Maximum Size:不受控情况下最大堆内存大小,起始就是我们在用largeheap属性时候,可以系统获取最大堆大小...2.3 对象分配和GC 1. 调用函数dvmHeapSourceAlloc在Java堆上分配指定大小内存。如果分配成功,那么就将分配得到地址直接返回给调用者了。...GC执行完毕后,再次调用函数dvmHeapSourceAlloc尝试轻量级内存分配操作。如果分配成功,那么就将分配得到地址直接返回给调用者了。 4....如果调用函数dvmHeapSourceAllocAndGrow分配内存成功,则直接将分配得到地址直接返回给调用者了。 6. 如果上一步内存分配还是失败,这时候就得出狠招了。

1.4K80

.NET面试题解析(06)-GC与内存管理

如果内部出现异常依然释放资源吗? 8. 解释一下C#里析构函数?为什么有些编程建议里不推荐使用析构函数呢? 9. Finalize() 和 Dispose() 之间区别? 10....返回内存地址: 返回对象内存地址给引用变量。 ? GC垃圾回收 GC是垃圾回收(Garbage Collect)缩写,是.NET核心机制重要部分。...垃圾回收基本流程包含以下三个关键步骤: ① 标记 先假设所有对象都是垃圾,根据应用程序根指针Root遍历堆上每一个引用对象,生成可达对象图,对于还在使用对象(可达对象)进行标记(其实就是在对象同步索引块中开启一个标示位...任何一个新对象,当它第一次被分配在托管堆上时,就是第0代(大于85000对象除外)。  第1代,0代满了触发0代垃圾回收,0代垃圾回收后,剩下对象搬到1代。 ...终结队列是一个由垃圾回收器维护表,它指向每一个在从堆上删除之前必须被终结对象

54210

.NET面试题解析(06)-GC与内存管理

如果内部出现异常依然释放资源吗? 8. 解释一下C#里析构函数?为什么有些编程建议里不推荐使用析构函数呢? 9. Finalize() 和 Dispose() 之间区别? 10....返回内存地址: 返回对象内存地址给引用变量。  GC垃圾回收 GC是垃圾回收(Garbage Collect)缩写,是.NET核心机制重要部分。...任何一个新对象,当它第一次被分配在托管堆上时,就是第0代(大于85000对象除外)。  第1代,0代满了触发0代垃圾回收,0代垃圾回收后,剩下对象搬到1代。 ...终结队列是一个由垃圾回收器维护表,它指向每一个在从堆上删除之前必须被终结对象。...在托管堆上创建新对象有哪几种常见方式? new一个对象; 字符串赋值,如string s1=”abc”; 类型装箱;

59320

golang逃逸分析

但是性能角度出发,在栈上分配内存和在堆上分配内存,性能差异是非常大。...在堆上分配时,必须找到一块足够大内存来存放新变量数据。后续释放时,垃圾回收器扫描堆空间寻找不再被使用对象。...在堆上分配内存,一个很大额外开销则是垃圾回收。Go 语言使用是标记清除算法,并且在此基础上使用了三色标记法和写屏障技术,提高了效率。 函数参数是传递,且在调用时立即执行拷贝。...GetUserInfo 函数返回为 *UserData 指针类型,然后 将变量userInfo 地址返回,此时编译器判断该可能会在函数外使用,就将其分配到了堆上,所以变量userInfo就逃逸了...如果想要减少垃圾回收时间,提高程序性能,那就要尽量避免在堆上分配空间 总结一下 函数返回变量指针时,这个变量逃逸 当觉得栈上空间不够时,会分配在堆上 在切片上存储指针或带指针时候,对应变量逃逸

57620

Go并不需要Java风格GC

内存碎片及其对GC设计影响。为什么这对Java很重要,但对Go就不那么重要。 类型以及它们如何改变GC。 分代垃圾收集器,以及Go为什么不需要它。...由于这个原因,Java中所有对象——除了整数和浮点等基本类型——都被设计为在堆上分配。在讨论内存分配时,我们通常会区分所谓堆和栈。...这就是为什么Java将它们分配对象分成两组: 老年对象——在GC多次标记和清除操作中幸存下来对象。每次标记和扫描操作时,更新一个分代计数器,以跟踪对象“年龄”。...它逃逸了是因为它被返回了。这意味着必须在堆上分配values。 然而,在第二个例子中,指向values指针并不会离开nonEscapingPtr函数。...C#开发人员会尽量减少大对象使用,因为不能安全地使用与指针相关代码。我们必须假设c#开发人员更喜欢复制类型而不是使用指针,因为这可以在CLR中安全地完成。这自然带来更高开销。

86930
领券