JAVA中的垃圾回收与内存分配-1

Java的JVM中的堆和栈

  • 通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;
  • 而通过new关键字和构造器创建的对象则放在堆空间。
  • 堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为Eden、Survivor(又可分为From Survivor和To Survivor)、Tenured;
  • 方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;
  • 程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在常量池中,常量池是方法区的一部分。
  • 栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError。

Java内存分配和垃圾回收

Java语言中一个显著的特点就是引入了垃圾回收机制,使C++程序员最头疼的内存管理的问题迎刃而解,毕竟C++中的各种构造函数和析构函数能让我们头疼的找不到妈妈。但是既然有了垃圾回收机制,Java的运行效率还是明显的慢于C++,通过这篇文章,我们详细了解Java的内存管理机制与C++的区别,让我们对Java的底层设计更为了解。
JVM内存的分配与回收大致可分为如下4个步骤: 何时分配 -> 怎样分配 -> 何时回收 -> 怎样回收.

一般认为new出来的对象都是被分配在堆上的,其实这个结论不完全正确,因为是大部分new出来的对象被分配在堆上,而不是全部,实际上,还有两个地方可以存放new对象,分别是:栈和TLAB(Thread Local Allocation Buffer)。

怎样分配-JVM内存分配策略

Java的堆和栈

  • 首先明白一点:我们所讨论的Java中的堆(heap)和栈(Stack),都是JVM内存中的概念,都是指的物理内存memory中的存储空间。不涉及CPU寄存器。

什么是堆,什么是栈?

我们先上一张图:
heapAndStack
和栈都是java用来在内存中存放数据的地方,与C++不同的是,java自动管理堆和栈,程序员不能自行设置堆和栈。
java中的堆就是运行时存储数据的区域,类的实例对象可以通过new等指令建立从中分配空间。堆是由jvm自动垃圾回收器负责的,堆的优势是可以动态的分配内存大小,存储空间可以自动回收。但是缺点是,由于实在运行时动态进行空间分配,存取速度较慢。
的优势是:存取的速度都比堆要快,仅次于寄存器。栈数据可以共享,但是缺点时,栈空间中的数据大小和生存期必须是确定的,缺乏灵活性。栈主要存放一些基本类型的变量int, short, long, byte, float, double, boolean, char和对象句柄(引用)。

看到这里,也就明白了一些基础概念:在Java中,基本数据类型的声明和赋值,都是在栈空间中实现的。

  • 栈就像一个有序序列,而且有个很重要的特殊性,就是存在栈中的数据可以共享:
    来看下面一个例子:
    1
    2
    3
    int a = 1;
    int b = 1;
    int c = 2;

编译器处理的过程:
首先对于第一行,会在栈中创建一个变量,其引用为a,然后查找栈内存中是否有1这个值:
(1)如果没有,就给这个变量赋值为1,然后a指向这个变量;
(2)如果有,就直接让a直接指向1;
所以这段程序,实际上栈中只为两个变量开辟了内存空间,一个存1,一个存2,而a和b都是指向1的引用,c是指向2的引用。

  • 堆就像它的名字一样,就是一堆!!放在那里,很多很乱~
    上面的形容可能不是很贴切,但是堆相比于栈而言确实无序很多,大很多,那么堆中存放的都是那些内容呢?
    我们还是用一段代码来说明:
    1
    Person per = new Person();

我们看上面这段代码,在Java中我们常这样写,但是实际上,这段代码包含了两步,分别是:

1
2
Person per = null; // 声明
per = new Person(); // 实例化

这样这两部分操作就分别用到了栈空间和堆空间,它们在内存中的划分是这样的:
newPer
堆内存用来存放所有new 创建的对象和 数组的数据,而且它的内存是可以动态调整的,对象的声明周期也不不需要明确。
当堆对象对应的栈引用被销毁后,堆对象自然也就变成了无引用状态,也就会被GC回收。这部分内容我们后续会接着介绍。

Donate comment here