内存管理与不安全代码

***************************************内存管理**********************************************************

===================================栈:
1,存储着值类型(方法的参数存储在栈中)

2,高性能

3,生存周期必须嵌套(缺点)

结构是值类型,存储在栈中。结构实例化(new)不会在栈中分配空间

===================================托管堆(与传统的堆相比有很显著的优势):

1,存储着引用类型(对象成员的值类型也存储在堆上)

2,可以对数据的生存周期进行强大的控制

3,建立引用变量的过程比建立值变量的过程复杂,性能开销大

===================================析构函数(必须有垃圾回收器调用):

1,垃圾回收器销毁对象之前执行

2,c#无法确定垃圾回收器何时执行,不能在析构函数中放置 需要在某一时刻执行的代码

3,c#析构函数的实现,会延迟对象从内存中销毁的时间。

4,频繁使用析构函数,对性能会有影响

===================================垃圾回收器

System.GC.Collect();  //强制对所有代进行垃圾回收
System.GC.SuppressFinalize(object);  //不掉用对象的终结器(析构函数)

***************************************不安全代码**********************************************************

===================================1,用unsafe关键字编写不安全代码

//配置:选中项目反键->属性->生成->勾选允许不安全代码

    //标记类
    unsafe public class Student
    {
        //标记字段
        unsafe int* pAge;
        //标记方法
        unsafe void getType(int* a)
        {
            //标记代码段
            unsafe
            {
                int* pAbc;      //声明指针语法
            }
        }
    }

===================================2,指针的语法

            unsafe
            {
                int* pWidth, pHeight;
                double* pResult;
                byte*[] pByte;
                //&:表示“取地址”,并把一个值数据类型转换为指针,例如,int转换为*int。这个运算称为【寻址运算符】
                //*:表示“获取地址内容”,把一个指针转换为一个值数据类型(例如:*float转换为float)。这个运算符被
                    //称为“间接寻址运算符”(有时称“取消引用运算符”)
                int a = 10;//声明一个值类型,给它赋值10
                int* pA, pB;//声明2个指针
                pA = &a;//取出值类型a的地址,赋值给指针pA
                pB = pA;//把指针pA的地址赋值给pB
                *pB = 20;//获取pB指向的地址内容,并赋值20
                Console.WriteLine(a);//输出20
            }

===================================3,将指针强制转化为整数类型

//只能转化为uing、long、ulong类型

int a = 10;
int* pA, pB;
pA = &a;
uint address = (uint)pA;//将指针地址强制转换为整数类型
pB = (int*)address;//将整数类型强制转换为指针
*pB = 20;//指针指向a
Console.WriteLine(a);//输出20

===================================4,指针类型的强制装换

int b = 10;
int* pIa;
double* pDa;
pIa = &b;
pDa = (double*)pIa;//将int*强制转换成double*

===================================5,void指针(不指向任何数据类型的指针)

int c = 10;
int* pAA;
pAA = &c;
void* pVa = (void*)pAA;//转换viod指针

===================================6,指针算数的运算(不允许对void指针进行运算)

p+x*(sizeof(T))
p:指针的地址
x:加上的数值
T:类型的大小

int d = 10;
int* pId;//如果地址为100000
pId = &d;
pId++;//结果:100004(int类型的大小为4个字节)

===================================7,sizeof运算符(只能求出值类型的大小)

int x = sizeof(int);

===================================8,结构指针:指针成员访问运算符

①指针不能只想任何引用类型
②结构里面不能包含引用类型

MyStruct* pStruct;
MyStruct ms = new MyStruct();
pStruct = &ms;
//--取地址内容赋值为10
(*pStruct).X = 10;
pStruct->X = 10;
//--取地址赋值给pIs
int* pIs1 = &(ms.X);
int* pIs2 = &(pStruct->X); 
//结构
struct MyStruct
{
        public int X = 1;
        public int Y = 2;
}

===================================9,类成员指针

Person p = new Person();
fixed (int* pIp1 = &(p.X), pIp2 = &(p.Y))
{
}//pIp1和pIp2的生命周期
//类
class Person
{
     public int X;
     public int Y;
}

===================================有趣的实验

unsafe
{
//有趣的问题:为什么b的值改变了
//回答:因为i的地址指向了b
int a = 10;
int b = 20;
int* i;
i = &a;//将a的地址赋值给指针i
i -= 1;//将i的地址-1(相当于向下移动4个字节(int类型的大小为4个字节))
*i = 30;//取出i指针指向的内容赋值为30
Console.WriteLine(b);//输出30
}
时间: 2024-12-13 20:13:44

内存管理与不安全代码的相关文章

oc内存管理总结(一)

**内存管理 问题 1.什么是ios内存管理? 就是在对象不再被使用的时候,把它即时的从内存中清除掉 2.为什么要使用内存管理? 1.严格的内存管理,能够是我们的应用程在性能上有很大的提高 2.如果忽略内存管理,可能导致应用占用内存过高,导致程序崩溃 3.系统判断一个对象是否要被销毁的依据是什么? 每个对象创建出来的时候,都有一个retainCount属性,默认值是1,当retainCount = 0的时候,系统就会将该对像销毁 4.如何使对象的retainCount 值增加? 调用retain

内存管理池

1.如果想要调用release,必须开启ARC 2.[实例对象 autorelease] 这个方法就是吧实例对象放到自动释放池中.(内存报警或者程序结束时自动释放) 3.@autoreleasepool  {} 自动释放池. 自动内存管理/ARC(Automatic Reference Counting) 1.自动内存管理 编译器自动的添加完成了内存管理的引用计数代码.(苹果公司支持用的) 2.ARC使用原则 3.ARC/MRC混编 ARC原则 1.代码中不能使用retain,release,a

FreeRTOS 动态内存管理

本章节为大家讲解 FreeRTOS 动态内存管理,动态内存管理是 FreeRTOS 非常重要的一项功能,前面章节讲解的任务创建. 信号量. 消息队列. 事件标志组. 互斥信号量. 软件定时器组等需要的 RAM 空间都是通过动态内存管理从 FreeRTOSConfig.h 文件定义的 heap 空间中申请的. 动态内存管理介绍FreeRTOS 支持 5 种动态内存管理方案,分别通过文件 heap_1,heap_2,heap_3,heap_4 和 heap_5实现,这 5 个文件在 FreeRTOS

java Hotspot 内存管理白皮书

原文见:http://www.open-open.com/lib/view/open1381034220705.html.查阅资料后,对原文做了补充. 文中关于JVM的介绍基于JDK1.6的Hotspot虚拟机,其他虚拟机中的实现可能会有所不同. 1引言 一个健壮的 Java平台,拥有一个自动内存管理机制,它为开发者们屏蔽了复杂的内存管理操作. 本 文提供了一个关于java Hotspot 虚拟机中内存管理机制的简单概述,它描述了一个可用于垃圾回收的内存管理器,并且提供了关于选择和配置一个回 收

[转载]linux段页式内存管理技术

原始博客地址: http://blog.csdn.net/qq_26626709/article/details/52742470 一.概述 1.虚拟地址空间 内存是通过指针寻址的,因而CPU的字长决定了CPU所能管理的地址空间的大小,该地址空间就被称为虚拟地址空间,因此32位CPU的虚拟地址空间大小为4G,这和实际的物理内存数量无关.Linux内核将虚拟地址空间分成了两部分: 一部分是用户进程可用的,这部分地址是地址空间的低地址部分,从0到TASK_SIZE,称为用户空间 一部分是由内核保留使

go的内存管理(一)

进程里面的堆和栈 我们知道进程之间内存是隔离的不共享.所以一般说到内存就是指的一个进程用到的内存. 而一个进程的内存一般可以分为 5个区:栈区, 堆区, 静态区(全局区), 文字常量区,代码区.而我们主要理解栈区和堆区,其他3个区里面的内容都是静态的. 栈区: 函数里面涉及到几乎大部分内容都在栈区,比如函数的实参,局部变量,操作符. 优点: cpu处理简单速度快,函数返回,栈区里面的空间就释放,而且对应线程是唯一的(并发安全). 缺点: 数据结构导致操作不灵活,生命周期短:一般在编译期间就决定了

C语言的内存管理分析 栈区 代码区 堆区 静态区 常量区

系统为了管理内存 把内存划分了几个区域 1> 栈区 栈区之中的数据在栈区之中以栈的形式进行存储. 栈区的特点:数据是先进后出, 放在栈区里面存放的是局部变量.(例如定义在函数内部的变量) 栈区之中的数据(局部变量)的作用范围过了之后,系统就会回收自动管理栈区的内存(分配内存 , 回收内存),不需要开发人员来手动管理 2> 堆区 高效的使用内存 这里的内存可以由程序员自己手动管理 高效的使用内存  例如: 申请内存 释放内存.优化内存 ARC 申请内存的函数 malloc()  memary a

Arc 自动内存管理 分类Category 类扩展 Block 代码段 和 Protocol协议的一些简单知识的总结

1. Arc的使用 Arc是自动内存管理: arc的使用原则 1).只要对象没有任何强类型指针引用就会被释放’. 2).只要对象被任何强类型指针指引就不会被释放. 弱指针:__weak 被__weak修饰的指针就被称为弱型指针: 强类型指针 默认的指针都是强类型指针: 被__strong修饰的指针也是强类型指针. 使用Arc时可以重写dealloc方法,但是在重写方法时不能手动调用[super dealloc]: 在Arc中通过@property生成的属性如果是OC的对象那么要用Strong来修

iOS性能优化之内存管理:Analyze、Leaks、Allocations的使用和案例代码 -[转载]

最近研究代码质量检测问题,在网上找的相关资料咱是如下: 一. 一些相关概念 很多人应该比较了解这块内容了...可以权当复习复习... 1.内存空间的划分: 我们知道,一个进程占用的内存空间,包含5种不同的数据区:(1)BSS段:通常是存放未初始化的全局变量:(2)数据段:通常是存放已初始化的全局变量.(3)代码段:通常是存放程序执行代码.(4)堆:通常是用于存放进程运行中被动态分配的内存段,OC对象(所有继承自NSObject的对象)就存放在堆里.(5)栈:由编译器自动分配释放,存放函数的参数值