堆,栈和GC的个人理解
int 类型是值类型,值类型保存在栈里面,栈是先进后出
而object是引用类型,里面的值保存在堆里面,而引用名在栈里面
然后所有的引用类型都保存在堆里面,而值类型如果被引用类型包住,比如引用类型的方法,里面的值,就会保存在堆里面,而没有包住,或者new,则会在栈里面,new的话,是因为是编译时新建的,所以出现在栈里面
为什么栈要先进后出呢?比如先定义一个int A,然后int B=A,此时如果要删除,就是从后往前删,肯定要先删B,再删A,不然就会出错,这就是先进后出的原因
然后拆箱装箱是什么呢,就是把一个值类型给引用类型,引用类型再给值类型,就是把值放进堆这个箱子里面,然后再从堆这个箱子取出到栈里面.拆箱和装箱会造成一定的性能损耗,一般是父子类才会发生这种情况
int a=1; object o=i; int b=(int)o;
而一个引用类型如果把值等于另一个引用类型,而且原来的值没有其他引用的话,就会变成垃圾,需要回收,而回收就需要GC了
GC
GC是c#的回收机制,是在内存不够用的情况下,回收内存中的托管资源,来节省内存,而非托管资源则是需要手动回收
托管资源是什么呢?就是堆里面的东西,而非托管资源呢,则是外面的,比如数据库,excel表,txt文件,这些就没办法了,只能手动的,比如SqlConnection的Dispose手动结束
不过现在可以用using来自动回收,不必手动回收了.
然后回收的东西,则是垃圾,而垃圾就是完全访问不到的东西
比如定义一个引用类型,然后让这个引用类型等于另一个,那么原来那个引用的东西就已经访问不到了,或者在一个代码块里面,结束这个代码块了,里面的东西也自然清空了,不然不同的方法,同名的变量,不就冲突了吗,所以结束就自动删除,但是堆里面东西还在,就要清除
而清除的时间是不定的,并且清除的时候,会阻塞所有线程,不然清除的时候加一个,咋清除啊
然后清除的顺序,清除是首先把所有东西标记为0,然后清除之后,就会把余下的标记为1级,下次再回收的时候,首先从0开始,然后清除到1,再把1的标记为2
好了,说完原理后,就来说说是怎么回收的,首先嘛,肯定是检测是否手动调用了回收方法Dispose,这个方法很多托管资源都有,如果调用了的话,就回收,并且阻止析构函数的调用
然后这个析构函数又是什么呢?这个析构函数是防止忘记手动调用而自动用的,不过也不能过度依赖,万一出问题呢?所以还是手动用Dispose吧,不过现在封装的很好了,比如,using(SqlConnection conn=new
SqlConnection())就会在结束后自动调用Dispose,然后析构函数是什么呢?
析构函数用于释放被占用的系统资源
析构函数的名字由符号“~”加类名组成,比如类名A,析构函数就是~A。
使用析构函数时,应该注意下面的问题:
只能在类中使用析构函数,不能在结构中使用析构函数。
一个类只能有一个析构函数
不能继承或重载析构函数
析构函数只能被自动调用
析构函数没有任何修饰符、没有任何参数、也不返回任何值
内存泄漏
然后还有一点就是内存泄漏,这个问题很少出现的,一般都是计算机给程序分配的内存小于程序需要的,有2种情况
1,程序问题.比如我定义了大量静态参数,又无法回收,然后就会出现这种情况
2,电脑问题,同时多个程序跑,然后内存小,就这样了
最后就是关闭程序的时候,这个时候就不是回收了,而是程序退出,不过也会一次GC
.
- 点赞
- 收藏
- 分享
- 文章举报
- java中静态信息,成员信息的个人理解,构造器与重载
- 深入理解全局编录服务器GC
- 对Python装饰器的个人理解
- 浅谈对java-GC的理解
- git个人理解
- QT 中shot(槽)的个人理解和一点笔记
- RxJava个人笔记,具象化理解
- 关于abstract的个人理解
- 函数对象和函数适配器的个人理解。我是一个小菜鸡
- 关于python中numpy.argpartition函数的个人理解
- 浅谈委托和事件(个人理解)
- 引用和指针的区别个人理解
- ios中对protocol协议的个人理解(一,对事件的监听)
- 个人对回调函数的理解
- JQuery trigger 个人理解手记
- 清除数组元素的方法:splice的个人理解
- Python中@修饰符的个人理解
- 关于装饰者模式的个人理解
- 初学SpringMVC 小总结(有些术语说的不准确以后会加强,有些只是我个人理解,发现有问题可以告诉我)
- 两种并发模型 的理解(个人理解)