GC与内存分配

垃圾收集(Garbage Collection, GC)

众所周知,Java的内存管理由虚拟机自动完成,那么这背后的原理到底是什么,今天就来简单了解一下。在此之前,我们要先知道Java的内存区域有哪些部分组成

虚拟机数据区

Java虚拟机管理的几个运行时数据区如下图所示:
网图,侵删
对于每个部分的功能这里不详细展开。简单来说:

  • 方法区
    方法区是线程共享的内存区域,用于存储已被虚拟机加载各种数据资源如类信息、常量等;


  • 堆是java虚拟机所管理的内存中最大的一块,几乎所有的内存实例都在这里分配内存。是垃圾收集器管理的主要区域,简称为“GC堆”。堆又分成了新生代和老年代,一般老年代与新生代的大小比为2:1;而新生代中又包含Edenn与Survivor(包括to、form),比例为8:1:1


  • 虚拟机栈是java方法执行的内存模型(jmm,关于jmm以后会具体展开介绍):每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。具体指虚拟机栈中局部变量表,局部变量表存放了编译器可知的各种基本数据类型、对象引用和返回地址,局部变量表所需要的空间在编译期间完成分配

  • 本地方法栈
    区别于虚拟机栈为虚拟机执行java方法服务,本地方法栈为虚拟机使用到的Native方法服务(一般是C语言实现的)。

  • 程序计数器
    程序计数器是一块较小的内存空间,控制着当前线程的执行。每条线程都有一个独立的程序计数器,且互不影响,独立存储。此内存区域是唯一一个java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。(相当于保存当前线程的状态,多线程)

垃圾回收算法

堆中存放着几乎所有的对象实例,因此我们聚焦于堆的垃圾回收

  1. 引用计数算法
    给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值减一;任何时刻计数器都为0的对象就是不可能再被使用的,但是它很难解决对象之间相互循环引用的问题,即A.instance=B;B.instance=A
  2. 根搜索算法
    通过"GC Roots"的引用链搜索,找到一个没有任何引用链的对象,则该对象不可用,可作为GC Roots的对象包括:栈中引用的对象、方法区类静态属性引用的对象、方法区中的常量引用对象、本地方法栈中JNI的引用对象等(说的很清楚了)
minor GC 与 full GC

简单来说,当我们不断的创建对象的时候,我们的新生代的Eden内存会逐渐被充满,当Eden不够用的时候,就会发生发生minor GC(GC Roots),并把依然存活的对象的年龄加一,然后转移到Survivor中,当对象的年龄为15时(Survivor的对象每活过一次minor GC,就增加一岁),则把对象加入老年代。(这是默认情况)
当老年代的剩余内存无法装载新生代存活的对象的时候和无法装载大对象的时候就会发生full GC(需要注意major GC 与 full GC的区别)。
GC的发生往往意味着Stop the world,因此jvm调优的主要目的就是减少GC,尤其是减少full GC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值