垃圾收集(Garbage collection, GC)

收集原理:

、引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加一;引用实效,就减一;它的问题是无法解决循环引用。

2、可达性分析算法:以一系列被称为‘GC Roots’的对象为起点,像下搜索,能到达的对象为可用,否则为不可用。
GC Roots对象包括:
虚拟机栈(栈帧中的本地变量表)中引用的对象
方法区中类静态属性引用的对象。
方法区中常量引用的对象
本地方法栈中JNI(即一般说的Native方法)引用的对象。

finalize方法

、如果一个对象没有覆盖finalize方法,当对象被回收打时候,不会执行;
2、如果有覆盖,但是这个对象之前已经执行过一次这个方法,当对象被回收的时候,也不会执行;
3、GC时,回收掉一个对象,如果它有覆盖finalize方法,并且之前没有被调用过,并不马上销毁它,而是将它移到F-Quene队列,并又虚拟机启动一个优先级低的Finalizer线程执行它,但是并不保证
等待它结束。

GC算法:

、标记-清除算法(Mark Sweep):
先标记不可达队对象,然后统一清除;
不足是会产生内存碎片;而且效率也不高 2、复制算法:
将内存2等分,当一份快用完时,将可达对对象复制到另一份,然后清空当前对象。
优点是效率高,确定是内存利用率低。 3、标记整理算法:
先标记可达的、不可达的对象,然后将可达的内存前移,最后直接清理掉后面的对象。 4、分代收集算法:
将内存划分为几块,然后根据每块的特点选择不同的算法。例如:新生代、老年代;

安全点、安全区域:

目前所有的GC回收时,都需要暂停用户线程,但是用户线程并不是在每一个地方都能够被GC线程暂停。目前采用的策略是,GC发出一个中断型号,用户线程每在到达安全点点时候,去读这个状态,决定是否
暂停。
上述策略解决不了,在中断信号发出之前用户线程已经进入了挂起或者等待状态(此时不在安全点);所以提出安全区点概念;
安全区:
指一段区域的代码段,引用不会发生变化。
线程在进入安全区点时候,会标记自己已经进入了安全区,此时如果发起GC,可以不用理会。如果线程离开安全区时,GC已经完成GC Roots对象的枚举,哪线程继续执行,否则需等待枚举完成。

收集器:

、初生代收集器:
Serial:单线程的,并且会STOP THE WORLD,STW,即在GC到时候会停止其他用户线程;采用复制算法 ParNew:多线程的,线程数和CPU数相同,其他和Serial相似; Parallel Scavenge:与ParNew 相似,其目标是达到可控的吞吐量(Throughput),吞吐量就是CPU用于用户线程的时间/CPU的总多时间;但是它不关注停顿时间。 2、老年代收集器:
Serial Old:Serial 的老年版;同样是采用单线程收集器;采用标记-整理算法;另外一个用途是作为CMS收集器的备案; Parallel Old:Parallel Scavenge的老年班; CMS(Concurrent Mark Sweep):使用标记-清除算法;以最短回收停顿时间为目标的收集器;将回收分为4各步骤:
a、初始标记:需要STW用户线程
b、并发标记:可以和用户线程并发执行,比如有4各用户线程,4个CPU这个时候GC线程也会和用户线程轮流使用CPU。没有阻塞,即为并发。并行指同时运行。
c、重新标记:需要STW
d、并发清除:可以并发 G1收集器:目前在低停顿时间上已经可以和CMS媲美,在低吞吐量上面没有表现的更加优秀。
总结:目前主流的虚拟机都是使用分代回收的机制;
1、新生代和老年代可采用不同的收集器,互相配合完成回收任务,虚拟机可以使用参数配置具体采用那种垃圾回收组合
2、将堆分为新生代和老年代,新生代又分为一个Eden区,2个Survivor区,其中通常Eden / Survivor = 8, 也可以使用参数配置。
3、通常新生代使用一个Eden、一个Survivor,回收时,将可达对象copy到另外一个Survivor;如果不够,就移动到老年代,如果再不够就启动Full GC,还是不够就OOM
4、大对象(新生代放不了,或者超过了设置的值)或者长期(4bit,默认15次GC,或者自定义的)存活对象被移入年老代;
5、android 采用的可能是CMS策略变种。

Java 垃圾收集与内存回收的更多相关文章

  1. Java进阶3. 内存回收机制

    Java进阶3. 内存回收机制 20131029 前言: 学过C++的都知道,C++中内存需要程序员自己维护.说道这里,很多开发的同学就感觉很痛苦,当他转向Java的时候,就会说你看Java多好啊,程 ...

  2. JAVA虚拟机:内存回收策略及算法

    java虚拟机中的程序计数器区.虚拟机栈区.本地方法栈区3个区域是随着线程的创建而创建,随着线程的结束而结束时,内存自然得到回收,所以这三个区域不需要过多考虑内存的回收问题. java虚拟机中的方法区 ...

  3. Java基础-JVM内存回收

    Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对象分为年青代(Young).年老代(Tenured).持久代(Perm),对不同生命周期的对象使用不同的算法.( ...

  4. 重读《深入理解Java虚拟机》二、Java如何分配和回收内存?Java垃圾收集器如何工作?

    线程私有的内存区域随用户线程的结束而回收,内存分配编译期已确定,内存分配和回收具有确定性.共享线程随虚拟机的启动.结束而建立和销毁,在运行期进行动态分配.垃圾收集器主要对共享内存区域(堆和方法区)进行 ...

  5. JVM笔记3:Java垃圾收集算法与垃圾收集器

    当前商业虚拟机的垃圾收集都采用"分代收集"算法,即根据对象生命周期的不同,将内存划分几块,一般为新生代和老年代,不同的代根据其特点使用最合适的垃圾收集算法 一,标记-清除算法: 该 ...

  6. 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制

    一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...

  7. Java的内存回收机制

    原文出处: cnblogs-小学徒V 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C ...

  8. Java 内存回收机制 -说到点上了

    下面这个图,很清楚地说明对象在new的时候是怎样开辟内存空间的 其中对象new出来的,是栈内存,变量的开辟是堆内存 Java的一个重要优点就是通过垃圾收集器GC (Garbage Collection ...

  9. 《深入理解Java虚拟机》学习笔记之内存回收

    垃圾收集(Garbage Collection,GC)并不是Java语言的半生产物,事实上GC历史远比Java久远,真正使用内存动态分配和垃圾收集技术的语言是诞生于1960年的Lisp语言.经过半个世 ...

随机推荐

  1. 大数据处理对象CLOG BLOG

    File 文件类的使用 decimal 类型(规范小数的形式)  longtext 类型(存储字符大数据) 存入文本文件到数据库 InputStream FileInputStream CLOG 类的 ...

  2. CLR内存管理

    CLR管理内存的区域,主要有三块,分别为: 1.线程的堆栈:(在程序应该编译过程为值类型实例分配好内存) 用于分配值类型实例.堆栈主要由操作系统管理,而不受垃圾收集器的控制,当值类型实例所在方法结束时 ...

  3. LAMP安全设置

    1.设置MySQL密码,删除多余root账号 [root@localhost ~]# mysql -uroot -p mysql>set password=password("111& ...

  4. Linux启动ftp服务器530 Permission denied解决方法(已试,行)

    Linux启动ftp服务器530 Permission denied解决方法重新在虚拟机下安装了linux.现在我想启动linux自带的ftp服务器:#service  vsftpd  start . ...

  5. JQuery中动态生成元素的绑定事件(坑死宝宝了)

    今天在做项目的时候,遇到了一个前端的问题,坑了我好长时间没有解决,今天就记录于此,也分享给大家. 问题是这样的,首先看看我的界面,有一个初始印象: 下面是操作列所对应的JS代码: { "da ...

  6. Android中Service深入学习

    概述 1.当用户在与当前应用程序不同的应用程序时,Service可以继续在后台运行. 2.Service可以让其他组件绑定,以便和它交互并进行进程间通信. 3.Service默认运行在创建它的应用程序 ...

  7. [WinAPI] API 8 [获取磁盘空间信息]

    获取磁盘分区的总容量和空闲空间的容量可以使用GetDiskFreeSpace函数或GetDiskFree SpaceEx函数.GetDiskFreeSpace使用DWORD类型作为输出参数,由于DWO ...

  8. SQL——系统函数

    1) CASE CASE有两种使用形式:一种是简单的CASE函数,另一种是搜索型的CASE函数. [1]简单的 CASE 函数 Format: CASE input_expression WHEN w ...

  9. HTTP协议之chunk编码(分块传输编码

    Transfer-Encoding: chunked 表示输出的内容长度不能确定,普通的静态页面.图片之类的基本上都用不到这个. 但动态页面就有可能会用到,但我也注意到大部分asp,php,asp.n ...

  10. atitit.提升开发效率---MDA 软件开发方式的革命(5)----列表查询建模

    )----列表查询建模 1. 配置条件字段@Conditional 1 2. 配置条件字段显示类型为range----@Conditional(displayType = displayType.ra ...