Java内存区域

栏目: Java · 发布时间: 5年前

内容简介:根据 “Java 虚拟机规范”, Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.而其实一个 Java 程序可以理解为一个进程, 进程里面的资源共享即区分以下区域的私有和共享.

根据 “Java 虚拟机规范”, Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.

Java内存区域

而其实一个 Java 程序可以理解为一个进程, 进程里面的资源共享即区分以下区域的私有和共享.

私有:

  • 程序计数器: 当前线程所执行的字节码的行号指示器.
  • 虚拟机栈(VM Stack): 每个方法在执行时会创建一个 栈帧 来存储局部变量表, 操作数栈, 动态链接, 方法出口等信息. 主要是局部变量表, 存储了各种基本数据类型和对象引用.
  • 本地方法栈(Native Method Stack): 对于 Native 方法的存储.

共享:

  • Java 堆: 几乎所有的对象示例都要在这里分配内存, 也是 GC 的主要管理区域.
  • 方法区: 存储虚拟机加载的类信息, 常量, 静态变量, JIT 编译之后的代码.

回收

GC 方案常见的是 引用计数法根搜索算法 .

引用记数法
可达性算法

GC Roots 有以下几种:

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象.
  2. 方法区中类静态属性引用的对象.
  3. 方法区中常量引用的对象.
  4. 本地方法栈中 JNI 引用的对象.

对象引用

涉及到内存回收, Java中对对象的引用可以使用以下四种,分别为强引用,软引用,弱引用,虚引用。

参考地址 .

  1. 强引用(StrongReference)

强引用是使用最普遍的引用,如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。 (默认的引用方式)

  1. 软引用(SoftReference)

如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存 (即不抛出OOM错误) 。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存(下文给出示例)。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中.

  1. 弱引用(WeakReference)

弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此 不一定会很快发现那些只具有弱引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

  1. 虚引用(PhantomReference)

“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。 使用虚引用只是为了能够在对象回收时收到通知.

ReferenceQueue的用法(以PhantomReference为例):

ReferenceQueue queue = new ReferenceQueue (); 
PhantomReference pr = new PhantomReference (object, queue);
名字 引用方式 GC是否回收 是否 OOM
强引用 直接调用
软引用 .get 看内存情况
弱引用 .get
虚引用 null

回收

标记-清除算法

即回收算法分为”标记”和”清除”两个阶段, 先扫描一次标记所有需要回收的对象, 再扫描一次回收所有被标记地对象.

缺点:

  • 效率太低
  • 会产生大量不连续地内存碎片, 这些碎片会导致无法给大内存对象分配内存.

复制算法

将可用内存分为大小相等的两块, 每次只使用其中的一块. 回收时把存活地对象复制到另一块区域即可, 其他空间都可以清理掉.

缺点:

  • 可用内存直接变成一半了.

标记-整理算法

先扫描一次标记所有需要回收的对象, 再让所有的对象都向一端移动, 最后清理掉边界以外的内存.

分代回收

现在的商业虚拟机大部分都是分代回收算法, 分为新生代(young gen)和老生代(old gen), 其中 young gen 又分为 eden 区, from survior 和 to survior 区. 新生代的 GC 叫做 Minor GC, 老生代的 GC 叫做 Major GC / Full GC . 数据一开始会分配到 Eden 区(大对象直接进入 old gen), young gen 采用的是复制算法, 因为 young gen 的大部分数据都是回马上死亡的, 所以只需复制少部分存货的对象从 From survior 到 To survior. 当 young gen 的数据经历了几次 GC 后(默认15次), 它会从 young gen 移到 old gen. 而 old gen 采用的是标记-整理算法, 可以应用 old gen 中对象 100% 都存活的情况.

GC 日志

33.125: [GC [DefNew: 3324K->152K(3712K), 0.0025925 secs] 3324K->152K(11904K), 0.0031680 secs]

  • 33.125: Java 虚拟机启动以来经过的秒数.
  • GC 开头: 区分 GC 区域, 像这里的 DefNew 是 Serial 收集器的新生代区域, 还有 Full GC 表示全部 GC.
  • 3324K -> 152K(3712K): GC 前该内存区域的可用容量 -> GC 后该内存区域已使用容量(该内存区域总容量)
  • 0.0025925 secs: 该区域 GC 所占用的时间.
  • 3324K->152K(11904K): GC 前 Java 堆已使用容量 -> GC 后 Java 堆已使用容量(Java 堆总容量)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Computational Geometry

Computational Geometry

Mark de Berg、Otfried Cheong、Marc van Kreveld、Mark Overmars / Springer / 2008-4-16 / USD 49.95

This well-accepted introduction to computational geometry is a textbook for high-level undergraduate and low-level graduate courses. The focus is on algorithms and hence the book is well suited for st......一起来看看 《Computational Geometry》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具