【JVM基础】内存管理

来源:互联网 发布:ip更换软件 编辑:程序博客网 时间:2024/05/18 03:41

本篇主要了解一下JVM对内存的管理。

内存结构

  • 方法区:也称为永久区。类的定义,常量,静态变量,即时编译器编译后的代码等存放在该区域
  • 堆:主要是对象和数组数据。各线程共享资源。
  • 栈:
    程序运行时有一个线程在工作。就是调用程序的方法。方法中可能产生一些局部变量。对对象的引用存放在栈中。
    程序运行时可能有多个线程,因此它们的变量不能放在一起,必须分开存放。因此栈空间是线程私有的。
    栈帧:存储在用户栈上的(当然内核栈同样适用)每一次函数调用涉及的相关信息的记录单元。
  • 程序计数器:保存当前执行的位置
  • 本地方法栈:JVM调用本地方法时存放的位置

堆的结构

堆中还有一些更小的区域,比如新生代,老年代,永久代。

现在永久代中也会进行垃圾回收。

新生代和老年代根据存在时间的长短进行划分。对象刚刚产生的时候存放在伊甸园(Eden Space),一段时间后垃圾回收器会检查新对象,比较重要的对象留下来,移到From区(From Space)。过段时间以后再进行回收。经过若干次(默认15次)回收之后如果一个对象还存活,将会被移动到老年代(Tenured Space)中。

垃圾回收

程序员写Java的时候不需要考虑内存的回收,不会有内存泄漏的发生。

垃圾回收算法1

思路:如果对象B被对象A引用,则对象B将不被回收。

问题:如果两对象存在相互引用,它们永远不会被释放。

垃圾回收算法2:根节点引用

思路:从程序中根节点开始遍历。凡是不可到达的节点将被回收。

清除方法

标记清除

问题:采用标记删除的方法会产生内存碎片,可能导致后续的大对象无法保存

标记整理

问题:移动对象可能会影响性能

复制算法

思想:事先留一些内存空间,最多只用一半的空间,一旦发生需要垃圾回收时,将对象复制到预留空间中,然后将原先的一般清除掉,然后再复制回去。(From Space 和 To Space称为Survivor区,大小与Eden Space的比例是1:4)

需要垃圾回收时大部分的对象都是垃圾,所以不需要预留一半的空间,只需要留一小块就可以了。

垃圾回收器

Serial收集器:

  1. 单线程的收集器,”Stop the world”
  2. 对于运行在Client模式下的虚拟机来说是一个很好的选择
  3. 简单而高效。

新生代用复制算法,老年代用标记整理。

还没被淘汰哦

Serial Old

针对老年代的单线程收集器,标记-整理

ParNew收集器

  1. Serial收集器的多线程版本
  2. “Stop the world”

Parallel Scvenge收集器

  1. 吞吐量优先
  2. 新生代收集器,复制算法,并行的多线程收集器
  3. 并行(Parallel):多条垃圾收集线程并行工作,但此时用户线程处于等待状态
  4. 并发(Concurrent):只用户线程和垃圾收集线程同时执行
  5. 经常工作

CMS收集器

  1. 目标:取得最短的回收时间。用于服务端
  2. 标记-清除
  3. 与客户代码并发执行
  4. 4个步骤:初始标记,并发标记、重新标记、并发清除
  5. 优点:并发收集,停顿低
  6. 缺点:对CPU资源非常敏感,无法清除浮动垃圾

G1收集器

  1. 面向服务端应用的垃圾收集器
  2. 优点:并行与并发、分代收集、空间整合、可预测的停顿
  3. 步骤:初始标记、并发标记、最终标记、筛选回收

使用指定的收集器

-XX +UseSerialGC

0 0
原创粉丝点击