.NET Framework
.NET Framework-垃圾回收器实现内存的分配、释放,文件的操作和IO流
原创fayling865 ©著作权
©著作权归作者所有:来自51CTO博客作者fayling865的原创作品,请联系作者获取转载授权,否则将追究法律责任
回忆一下:CLR(动态语言运行时)的优点:
跨语言集成
跨语言异处理
增强的安全性
版本控制
部署支持
简化的组件交互模型
调试和分析服务
1、 .NET Framework的内存管理(面试):
.NET Framework的垃圾回收器管理应用程序的内存分配和释放,当使用new运算符创建对象时,运行库(CLR)都从托管堆中为该对象分配内存,只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间直到内存不够分配了,垃圾回收器才会执行回收释放一些内存。
实例化新对象的过程:
(1)计算字段所需空间
(2)对象所需空间:包括两部分,一部分是字段、另一部分是同步块索引和类型对象指针
(3)分配物理内存,新对象指针指向下一个可用内存区域
垃圾回收过程:
(1)标记阶段:从根标记遍历到的对象。
(2)压缩阶段:释放没有标记的对象内存,调整存在对象的位置
垃圾回收过程图如下:
代(Generation)是CLR垃圾收集器的一种机制,它存在的惟一目的就是提高应用程序性能,代表示的是对象在内存中的时间长短。
CLR支持3代内存(并不是应用程序的大小)
第0代对象预算容量为256k
第1代对象预算容量为2M
第2代对象预算容量为10M
说明:(1)CLR初始化时,托管堆中没有任何对象,此时添加对象是,为第0代对象;
(2)当在内存(托管堆)中一直放应用程序,直到内存大于256K,这时候就触发回收,将剩下的放入0代,把新进入程序的放入1代, 同理其他的。
垃圾回收过程如下图:
问题:垃圾回收器如何判断什么时候能知道是否可以回收某块内存区域?
解释:当使用new关键字创建对象的时候,运行库(CLR)都从托管堆中为该对象分配内存,同时线程堆栈中也有它的一个链接(压入),当程序执行完毕(线程堆栈先进后出),就会从堆栈中出去,此时相应标记托管堆中该对象所分配的内存空间可以回收,当为对象分配内存时,如果如果内存中(托管堆)中没有对象称为0代,当往托管堆中存放的对象所占的内存空间大于0代对象的预算容量(即256k),就会默认启动垃圾回收器将不用的内存释放出去,将剩下的放入1代,把新进入的对象分配的内存放入0代,同理其他的也是如此。
2、文件:是一些具有永久存储及特定顺序的字节组成的一个有序的、具有名称的集合;
流:提供一种向后备存储写入字节和从后备存储读取字节的方式,后备存储可以为多种存储媒介之一。正如除磁盘外存在多种后备存储一样,除文件流之外也存在多种流。例如,还存在网络流、内存流和磁带流等。
回忆一下:
以下情况要定义实例化类:
1)需要传递参数或当类型用的时候
2)对象要定义数组或集合的时候
文件操作
Directory类:用于公开创建、移动和枚举目录的静态方法,此类不能被继承,用时需要实例化,然后用对象访问,使用时直接类名加点访问。
DirectoryInfo类:用于公开创建、移动和枚举目录的实例方法,此类不能被继承用时需要实例化,然后用对象访问。
FileInfo类 :(先实例化然后用对象调用):提供创建、复制、删除和打开文件的实例方法,此类不能被继承,需要先实例化再使用。
File类:(先实例化然后用对象调用):提供创建、复制、删除和打开文件的静态方法,此类不能被继承,直接用类调用方法。
Path类(静态类):对包含文件或目录路径信息的实例化操作。
string path = @"D:\a.txt";
File.AppendAllText(path, DateTime.Now.ToString() + "\r\n");//向指定的路径的文件尾追加内容
File.WriteAllText(path, "saffh");//向指定路径的文件中添加内容覆盖原有的内容
Console.WriteLine(File.GetAttributes(path));//获得指定文件的属性(位枚举)
Console.WriteLine(Path.GetExtension(path));//获取指定文件的路径名
foreach (string s in Directory.GetLogicalDrives())
{
Console.WriteLine(s);
DriveInfo di = new DriveInfo(s);
Console.WriteLine(di.DriveType);//获取盘符的类型
}//获取某台电脑所有的盘符及类型
DirectoryInfo di1 = new DirectoryInfo(@"D:/a");
di1.Create();//在盘创建一个文件夹D
di1.Delete();//删除刚创建的文件夹D
递归的要素:1递归必须要做一个方法
2递归必须有一个变化的参数
小练习:用递归的方法实现检索某个指定路径的所有文件夹中的文件
class Program
{
static void Main(string[] args)
{
string path = @"D:\暑期实训";
DG(path );
}
static void DG(string path)
{
foreach (string str in Directory.GetDirectories(path))
{
DG(str);
}//遍历指定路径下的所有文件夹并递归输出文件夹中的文件
foreach (string str in Directory.GetFiles(path))
{
Console.WriteLine(str);
}//遍历指定路径下的所有文件并输出
}
}
3、IO-流:分为:文件流、网络流、内存流等,总是以字节数组的数据形式存储,
注:文件的读写编码要一致
Stream:抽象化的类,本身不能实例化,需要靠子类实现它。
文件流的使用:
1)文件流写
FileStream fs = new FileStream(path, FileMode.Create,FileAccess.Write);
string con = "大家好!";
byte[] bytes = Encoding.Default.GetBytes(con);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
2)文件流读
FileStream readfs = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] bytes1 = new byte[readfs.Length];
readfs.Read(bytes1, 0, bytes1.Length);
readfs.Close();
Console.WriteLine(Encoding.Default.GetString(bytes1));
利用文件流实现文件的写入和读取操作
string path = @"F:/ab.txt";
StreamWriter sw = new StreamWriter(path);
sw.Write("不错不错");
sw.WriteLine("还行");
sw.Close();
StreamReader sr = new StreamReader(path, Encoding.Default);
Console.WriteLine(sr.ReadToEnd());
while (!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
sr.Close();
小练习:利用流操作实现名片管理数据的持久化,将数据保存在指定的文件中
namespace ConsoleApplication1
{
class Card
{
public string Name
{
get;
set;
}
public string Company
{
get;
set;
}
public override string ToString()
{
return "姓名:" + Name + " 公司:" + Company;
}
}
class Program
{
static void WriteCards(List<Card> list)
{
string[] cardes = new string[list.Count];
int index = 0;
foreach (Card card in list)
{
cardes[index++] = card.Name + "|" + card.Company;
}
File.WriteAllLines(@"F:/cards.txt", cardes);
}
static List<Card> ReadCards()
{
List<Card> list = new List<Card>();
string[] cardes = File.ReadAllLines(@"F:/cards.txt");
foreach (string cardstr in cardes)
{
Card card = new Card();
card.Name = cardstr.Split('|')[0];
card.Company = cardstr.Split('|')[1];
list.Add(card);
}
return list;
}
static void Main(string[] args)
{
int count = 0;
while (count < 17)
{
Console.WriteLine("明白吗?");
count += int.Parse(Console.ReadLine());
}
foreach (Card card in ReadCards())
{
Console.WriteLine(card.ToString());
}
Card card1 = new Card();
card1.Name = "dddd";
card1.Company = "bbbb";
Card card2 = new Card();
card2.Name = "dfdddd";
card2.Company = "bbdfbb";
List<Card> list = new List<Card>();
list.Add(card1);
list.Add(card2);
WriteCards(list);
return;
}
}
}
上一篇:C#基础-完结篇
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Java实现基于清除后分配规则的垃圾回收器及其实现原理
Java实现基于清除后分配规则的垃圾回收器及其实现原理
垃圾回收器 java 递归 -
内存分配和垃圾回收
.NetFram
职场 休闲 垃圾回收 内存分配 .NetFrameWork -
Java垃圾回收器与内存分配策略
上一篇JVM内存模型讲述了Java虚拟机在运行时所管理的内存划分下的每个数据区域的各自用途,以及创建和销毁时间。
jvm 内存分配 GC 垃圾回收 jvm-GC -
【垃圾回收器、垃圾回收算法、空间分配担保】
文章目录SerialParNewParallel scavenge复制算法分代收集算法生代下使用复制算法,单线程运行的垃圾回收器,简单高效,没有线程交互.
java 开发语言 原力计划 老年代 垃圾回收器 -
.NET Framework-多线程&网络编程
&n
TCP/IP 多线程 -
整理的JVM垃圾回收机制和内存分配策略
整理的JVM垃圾回收机制和内存分配策略
老年代 java 垃圾收集 可达性 公众号