内存
- 1.堆和栈的本质是什么
- 2. java、Python等内存模型
- 3. java内存模型
- 3.1 java中堆和栈是如何实现的
- 4. Python内存模型
什么是内存
C/C++内存模型
堆区与栈区的本质
Java、Python等内存模型
Java内存模型
Jave中的堆区与栈区是如何实现的
Python内存模型
指针与引用
进程的内存模型
幻想大师-操作系统
总结
1.堆和栈的本质是什么
- 在编程语言中,堆区和栈区本质上都是内存,二者没有本质的区别
- 在数据结构和算法中,我们也有堆和栈的概念,但是那里指的不是内存,而是两种数据结构。
🚘🚘🚘 - 由于计算机的内存有限,我们才需要费劲心力提出堆栈的概念。
- 你会发现栈是一种非常巧妙的使用内存的方法,函数调用完毕后,函数运行过程中占用的内存就会被释放掉,只要你的程序写的合理(栈帧不会过大),那我们的程序就会一直运行下去,而不会出现内存不足情况,也不必担心内存释放的问题,这个过程是自动的。
- 但是如果程序员想自己控制内存,那么可以选择在堆上进行内存分配
2. java、Python等内存模型
- C++程序员面对的是 实实在在的物理内存,而 java、Python等程序面对的是 解释器,C++分配内存是直接在物理内存中进行,而Java、Pyhton等程序是将内存分配请求交给解释器,解释器再去物理内存上进行分配。
下图所示:内存布局Java、Python等程序员是看不到的只有解释器才能看到这些。
- java、Python等程序的一大优点就是内存自动化管理,而C++程序员需要自己来管理从堆上分配的内存,内存管理这一项被 Java、Python等程序中的解释器接管了,解释器的这项功能被称为“垃圾回收器”。
3. java内存模型
- java的内存模型直观同样有堆和栈的概念。内置数据类型比如 int ,直接放在栈上。引用类型:也就是 new 关键字定义的变量时分配在堆上的。
- 和C++一样,每个java函数在执行时都有自己的栈帧,随着函数的调用,栈不断扩大,函数调用完毕后栈帧回收。
3.1 java中堆和栈是如何实现的
一般情况下,当JVM运行一个 java函数时需要在堆上创建java函数的栈帧,然后把这些栈帧放入栈中(这里的栈是指具有先进后出性质的数据结构)。
🚘🚘🚘
因为JVM是C++程序,如何组织栈帧完全是 JVM设计者来决定的,只要栈帧具备先进后出的性质就可以。
void RunJavaFunction(JVM* jvm, string javaFunction)
{
// 先在堆上申请一块空间,用于存放java栈帧
stackFrame* frame = (stackFrame*) malloc(sizeof(stackFrame));
// 再把要使用的 栈帧push 到 JVM的函数调用栈中
jvm->stack->push(frame);
// 在申请的栈帧上执行 java函数
run(javaFunction, frame);
// 执行完毕后 pop 掉该函数栈帧
jvm->stack->pop();
}
JVM会在自己的堆中为 new修饰的对象创建内存,这里的 堆就是上图所示的堆。
4. Python内存模型
- Python的内存模型和Java其实类似。
- Python的解释器比较多,比如:CPython, PyPy等等。这里我们以Python默认的解释器 CPython为例说明。我们知道解释器其实就是一个C++程序,CPython也不例外。但是Python解释器将堆区分成了两部分:Object-specific memory 和 Python core两个区域。
- Object-specific memory 这个区域是专门存档PyObject对象的。 在Python中所有数据类型包括:int dict str 等都是一个对象,叫做 PyObject ,当我们在Python中创建一个变量比如 dict时,CPython就会在堆的上半部分(Object-specific memory)中分配一块内存创建一个 Pyobject 。
- Python core:所有非PyObject 的内存请求都在这里分配。