做一个java程序员很是幸福,不用管不用的对象如何被回收,但是我认为了解一下也不是坏事。

一、如何判断对象已经死亡?

在进行垃圾回收之前,第一件事肯定是判断对象是否已经死亡。
1、引用计数算法
给对象添加一个引用计数器,当程序中使用到这个对象的时候,计数器+1;如果引用失效,计数器-1,当计数器为0时,说明程序中不再使用这个对象,既可以回收。
问题:试想一下,当A对象中使用B对象,B对象中有方法使用A对象,完犊子,两个对象永远存在。

2、可达性分析算法(主流的商用程序语言的主流实现,都是基于此算法)
通过一系列GC Roots的对象作为起始点,当一个对象到GC Roots没有任何引用链相连,说明对象不可用,可以被回收。

那么GC Roots对象的选择非常重要,主要包括下面几种:
1、虚拟机栈中引用的对象
2、方法区中类静态属性引用的对象
3、方法区中常量引用的对象
4、本地方法栈中JNI(native方法)引用的对象

二、引用

在jdk1.2之前,引用是这么定义的:
如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称这块内存代表着一个引用。
在jdk1.2之后,对引用进行了扩展:
1、强引用
Student student = new Student(),这种就叫做强引用,这种只要引用存在,垃圾收集器永远不会回收对象。
2、软引用
有用但不是必需的对象,在系统将要发生内存溢出异常之前,把这些对象列进回收范围进行第二次回收。SoftReference表示软引用。
3、弱引用
非必需的对象,强度比软引用更弱一些,弱引用对象只能生存到下一次垃圾收集发生之前。WeakReference表示弱引用。
4、虚引用
无法通过虚引用取得一个对象实例,存在的唯一意义就是在这个对象被收集器回收时收到一个系统通知。PhantomReference表示虚引用。

三、垃圾回收算法

垃圾回收的算法有很多,逐一介绍。
1、标记-清除算法
首先通过上面介绍的GC Roots算法判断对象是否存活,然后将不存活的对象打上标记。如下:

缺点:

  • 效率问题,标记和清除两个过程的效率都不算高
  • 资源浪费问题:从图中可以看到,清除完之后的内存都是不连续的,产生了很多的内存碎片,这样以后内存分配其他大对象的时候,就无法分配了。

2、复制算法

复制算法将内存分为大小相等的两块,每次只使用一块,当一块内存快满的时候,就将还存活的对象复制到另外一块内存上,然后把已使用的内存一次性清理掉,这样会提高效率。缺点则是浪费内存了,一次只能使用一半。

大部分的商业虚拟机都是采用这种算法还回收新生代,在之前的博文中提到了新生代主要可以分为eden、from survivor、to survivor,
通常eden:survivor=8:1,因为大部分新生代中的对象,大概能有98%是朝生夕死的。

3、标记-整理算法

标记过程基于标记-清除算法,但是整理的时候则不一样,让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

4、分代收集

以上几种算法各有各的特点,当前主流的商业虚拟机对于不同的内存区域,例如新生代、老年代,不同区域的对象特点不同,所以使用不同的算法达到最佳的效果。

四、内存分配

1、对象优先在eden区分配,如果eden区内存不够,则触发一次minor gc。
minor gc:年轻代内存回收被称为minor gc。
major gc:清理老年代。
full gc:清理整个堆空间—包括年轻代和老年代。

2、大对象直接进入老年代
大对象:需要大量连续内存空间的java对象,例如很长的字符串以及数组对象。

3、长期存活的对象将进入老年代
如何判断对象是长期存活的,其实也简单,jvm给对象维护了年龄计数器。对象从eden区没有被回收掉,年龄+1,到了survivor区还是没被干掉,年龄+1,达到年龄的阈值后,放入到老年代。

深入理解java虚拟机(二)-----垃圾回收的更多相关文章

  1. 深入理解Java虚拟机之垃圾回收篇

    垃圾回收简介 ​ Java 会对内存进行自动分配与回收管理,使上层业务更加安全,方便地使用内存实现程序逻辑.在不同的 JVM 实现及不同的回收机制中,堆内存的划分方式是不一样的. ​ 简要地介绍下垃圾 ...

  2. 深入理解java虚拟机---3垃圾回收机制GC

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...

  3. 深入理解java虚拟机【垃圾回收算法】

    Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...

  4. 深入理解Java虚拟机(三)——垃圾回收策略

    所谓垃圾收集器的作用就是回收内存空间中不需要了的内容,需要解决的问题是回收哪些数据,什么时候回收,怎么回收. Java虚拟机的内存分为五个部分:程序计数器.虚拟机栈.本地方法栈.堆和方法区. 其中程序 ...

  5. 【深入理解Java虚拟机】垃圾回收

    引用计数算法 给对象加一个计数器,引用一次+1,引用时效就-1,当计数器=0时对象就不能再被使用: 实现简单,判定效率高:Java虚拟接没有使用,主要原因是很难解决对象之间循环引用问题: GC算法: ...

  6. Java虚拟机之垃圾回收详解一

    Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这 ...

  7. 每日一问:讲讲 Java 虚拟机的垃圾回收

    昨天我们用比较精简的文字讲了 Java 虚拟机结构,没看过的可以直接从这里查看: 每日一问:你了解 Java 虚拟机结构么? 今天我们必须来看看 Java 虚拟机的垃圾回收算法是怎样的.不过在开始之前 ...

  8. Java虚拟机之垃圾回收

    简述 Java与那些较传统的语言比如C++有个很大不同就是垃圾回收策略了.前者通常是虚拟机自动帮我们做了,而后者就需要我们手动来完成. Java虚拟机帮我们完成了垃圾回收,是不是意味着我们就不用完全去 ...

  9. Java 虚拟机 - GC 垃圾回收机制分析

    Java 垃圾回收(Garbage Collection,GC) Java支持内存动态分配.垃圾自动回收,而 C++ 不支持.我想这可能也是 为什么 Java 脱胎于 C++ 的一个原因吧. GC 的 ...

随机推荐

  1. lnmp之Nginx配置https加密访问

    配置lnmp之Nginx网站支持https加密访问 注: 1. 这里拿购买的(pxsnx.pxjy.com)证书来做样例 证书文件共有三个---> (pxsnxg.pxjy.com_ca.crt ...

  2. 虚拟网络学习笔记之一:VXLAN

    1. 什么是虚拟网络? 答:从架构角度考虑,我们可以采用与服务器虚拟化引入Hypervisor的方式一样,引入Nypervisor或者叫“虚拟网络管理平台”实现虚拟网络.虚拟网络必须像虚拟机一样,脱离 ...

  3. Python基础-python流程控制之顺序结构和分支结构(五)

    流程控制 流程:计算机执行代码的顺序,就是流程 流程控制:对计算机代码执行顺序的控制,就是流程控制 流程分类:顺序结构.选择结构(分支结构).循环结构 顺序结构 一种代码自上而下执行的结构,是pyth ...

  4. 创建表结构的sql语句

    1.创建表结构 表名: ODS_PSP_DIS_DAY_CALC create table ODS_PSP_DIS_DAY_CALC ( ID      CHAR(32)  NOT NULL, DIS ...

  5. winform使用PrintDocument控件打印以及oledb驱动

    代码,需要加入的控件:PrintDocument.PageSetupDialog.PrintDialog.PrintPreviewDialog.BackgroundWorker,控件的Document ...

  6. PyCharm中 Django1.11配置Mysql数据库

    1.Django 中配置MySQL数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': '数据库名称 ...

  7. leetcode4:两个排序数组的中位数

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 1.我的思路:直接用sort,时间复杂度应如 ...

  8. 转 Java操作PDF之iText详细入门

    转 Java操作PDF之iText详细入门 2016年08月08日 11:06:00 阅读数:19490 iText是著名的开放项目,是用于生成PDF文档的一个java类库.通过iText不仅可以生成 ...

  9. 解决Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules

    1.在eclipse的workspace里面找到该项目.settings文件夹 2.编辑org.eclipse.wst.common.project.facet.core.xml文件 <?xml ...

  10. Python语言学习之C++调用python

    C++调用python 在C/C++中嵌入Python,可以使用Python提供的强大功能,通过嵌入Python可以替代动态链接库形式的接口,这样可以方便地根据需要修改脚本代码,而不用重新编译链接二进 ...