Java GC简单理解

情景

做Android开发OutOfMemory很常见,内存泄漏的问题也经常遇到,但不知道具体发生了什么,所以简单了解一下Java的garbage collection。

Java运行时内存划分

程序计数器 Program Counter

一块很小的空间,指示当前线程的执行的字节码执行到了第几行。
线程私有,每个线程单独划分。
执行java方法:记录虚拟机字节码指令地址
执行native方法:值为undefined

虚拟机栈 Java Stack

执行java方法
一个线程的每个方法都创建一个帧栈(Stack Frame),帧栈存储局部变量表、操作站、动态链接、方法出口等。
方法调用是帧栈压栈到虚拟机栈,方法执行完成帧栈出栈。
线程私有

本地方法栈 Native Method Stack

等同与虚拟机栈,用来执行native方法。

堆区 Heap

存储对象实例。
创建的对象实例全部放在堆区。
GC的主要理解区域

方法区

在GC中也称为永久代。
用于存储已经被虚拟机加载的类信息、final常量、静态变量、编译器即时编译的代码等。
运行时常量池也包含在方法区,String常量池等。

Java内存分配机制

分代分配、分代回收。
在堆区中,分为年轻代以及年老代,分别按照不同的算法进行垃圾收集。
由于绝大部分的对象都活不了多久,通过分代的方式提升GC性能。

年轻代 Young Generation

除超出年轻代空间的大对象,对象的创建首先分配到年轻代。
年轻代也分为三个区域:Eden、Survivor0、Survivor1,按照8:1:1的大小进行划分。

Eden

伊甸园区,对象创建的第一站。
Eden装满之后,针对整个年轻代进行Minor GC,这里使用停止复制算法,仍然存活的对象放到空白的Survivor中,同时清空Eden和另一Survivor的所有空间。

Survivor

幸存者区,两个对等的内存空间,必须保证一个空间为空的状态,存在一个空间内存的浪费,但是相较频繁的Minor GC性能提升更大。
每次Minor GC将整个年轻代的存活对象放到空白的Sruvivor区,同时清空剩余空间。
单次Minor GC超过Survivor空间,将部分对象存储到年老代。
多次Minor GC任然存活的对象存储到年老代。

年老代 Old Generation

存储多次Minor GC任然存活的顽强对象和大对象,到了年老代的对象脱离了短命鬼区,只有当年老代慢了之后,触发Full GC/Major GC,但是相较与Minor GC频率低很多。这里使用标记整理算法

永久代/方法区

永久代的GC不是必须的。

回收废弃常量以及无用的类。
常量的回收很简单,没有引用了就可以被回收。
无用的类进行回收,必须保证3点:

  • 类的所有实例都已经被回收
  • 加载类的ClassLoader已经被回收
  • 类对象的Class对象没有被引用(即没有通过反射引用该类的地方)

算法具体分析

参考路径:jvm:停止复制、标记清除、标记整理算法(垃圾回收)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值