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

Java如何实现内存动态分配和内存垃圾的回收?

1、哪些内存需要回收(垃圾收集器内存回收的对象)?已经“死亡”的对象,那如何判定对象已经“死亡”了?

Java堆回收的内存:已经”死亡“的对象

方法区回收的内存:废弃的常量和无用的类

2、什么时候进行回收?什么情况下垃圾收集器自动回收内存?

3、如何回收?Java虚拟机是如何实现内存回收的?

(一)Java堆内如何判断对象已经“死亡”

1、引用计数算法:

算法思路:通过对象的引用计数器判断,引用的时候递增计数器,引用失效后递减计数器。

缺点:难以解决循环引用问题

2、可达性分析算法:

算法思路:判断对象到GC Root节点是否存在引用链,如果不存在则说明对象不可用。

缺点:(1)当GC Root点多的时候逐个检查消耗时间过多

(2)进行分析的时候GC需要停顿,停顿所有Java执行线程。

GC Root节点:主要存在全局性引用(常量,静态属性)、执行上下文(如栈帧的本地变量表)中,

具体可作为GC Root节点的有:

1)虚拟机栈(栈帧内的本地变量表)中引用的对象

2)方法区内的静态属性和常量引用的对象

3)本地方法栈中本地方法引用的对象

3、对象引用的划分

引用类型

特点和用途

内存回收时机

实现

强引用

操作引用对象。 不可回收 类似 Object boj=new Object();的引用

软引用

用来描述有用但非必需的对象,比强引用弱 第二次回收 SoftReference

弱引用

用来描述有用但非必需的对象,比软引用弱 下一次垃圾回收的时候,无论内存是否足够都进行回收。 WeakReference

虚拟用

实现对象在垃圾收集器回收的时候收到系统通知。最弱的引用关系 下一次垃圾回收的时候 PhantomReference

(二)方法区内如何判断废弃的常量和无用的类?

1、如何判定废弃的常量

和堆内存对象的存活判断类似

2、如何判定无用的类

成为无用类的条件(同时满足这个三个条件):

(1)所有实例对象都已经回收,Java堆中不存在该类的任何实例

(2)加载该类的ClassLoader已经回收

(3)类的Class信息不存在引用,不存在反射访问该类的方法

(三)垃圾收集器如何回收内存?

1、标记-清除算法

(1)算法实现:

分为“标记”和“清除”两个阶段,首先标记出需要回收的对象,标记完成后统一回收被标记的对象。

(2) 特点:

1)效率低

2)易产生大量不连续的内存碎片,内存空间碎片过多导致在分配大对象时候,没有足够的连续内存分配, 就有触发一起垃圾收集操作

2、复制算法

为了解决“标记-清除”算法的低效率问题,而提出的

(1) 算法实现:

将内存分为两个大小相等的内存区域,一半用于分配内存,另一半暂时不用,也就是只使用内存中的一半。等到该一半内存用完了,不足以分配更多的内存的时候,将该一半内存区域内的还存活的对象复制到另一半,然后将之前占用的一半内存区域清空。

(2)特点:

1)提升了效率,但是内存空间只使用了一半,属于用空间换效率

2)对象的存活率高的情况下,需要进行大量的复制操作,效率也会降低

3、标记-整理算法

根据老年代的特点,提出的算法

(1)算法实现:

同“标记-清除”算法类似,分为“标记”和“整理”两个阶段,首先标记出需要回收的对象,标记完成后将存活的对象向一端移动,然后直接清理掉端边界以外的内存。

(2)特点:

1)还是存在低效率的问题,标记过程和整理的过程效率低

4、分代收集算法

根据对象存活周期的不同将内存划分为新生代和老年代,然后根据各个年代的特点采用最适当的收集算法。

(1)算法实现:

年代

特点

内存回收算法

新生代 每次垃圾收集会有大批对象死去,只有少量对象存活 复制算法
(只需要复制少量的存活对象)
老年代 对象存活率高、没有额外的内存空间对它进行分配担保 标记-清理算法或者
标记-整理算法

(2)特点

根据对象存活周期的长短,采用不同的算法

 

(四)如何分配内存?(内存的分配策略)

1、对象优先在Eden分配

2、大对象(需要大量连续内存空间的对象)直接进入老年代

3、长期存活的对象直接进入老年代

重读《深入理解Java虚拟机》二、Java如何分配和回收内存?Java垃圾收集器如何工作?的更多相关文章

  1. (转)《深入理解java虚拟机》学习笔记3——垃圾回收算法

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

  2. 深入理解Java虚拟机二:垃圾收集与内存分配

    垃圾收集:垃圾收集要完成三件事,包括哪些内存需要回收,什么时候回收及如何回收. 1.需要回收的内存判定:没有引用指向原先分配给某个对象的内存时,则该内存是需要回收的垃圾 Java垃圾收集器在对内存进行 ...

  3. 《深入理解Java虚拟机》读书笔记3--垃圾回收算法

    转载:http://blog.csdn.net/tjiyu/article/details/53983064 下面先来了解Java虚拟机垃圾回收的几种常见算法:标记-清除算法.复制算法.标记-整理算法 ...

  4. Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏【转】

    Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏[转] 标签: javajvm线程泄漏 2015-03-11 19:47 1098人阅读 评论(0) 收藏 举报   ...

  5. Java虚拟机性能管理神器 - VisualVM(8) 查找JAVA应用程序耗时的方法函数【转】

    Java虚拟机性能管理神器 - VisualVM(8) 查找JAVA应用程序耗时的方法函数[转] 标签: javajvm监控工具性能优化 2015-04-07 16:47 1846人阅读 评论(0)  ...

  6. Java虚拟机性能管理神器 - VisualVM(6) 排查JAVA应用程序内存泄漏【转】

    Java虚拟机性能管理神器 - VisualVM(6) 排查JAVA应用程序内存泄漏[转] 标签: javajvm内存泄漏监控工具 2015-03-11 18:30 1870人阅读 评论(0) 收藏  ...

  7. Java虚拟机性能管理神器 - VisualVM(9) 排查JAVA应用程序线程死锁【转】

    Java虚拟机性能管理神器 - VisualVM(9) 排查JAVA应用程序线程死锁[转] 标签: javajvm监控工具性能优化 2015-03-11 19:59 1948人阅读 评论(0) 收藏  ...

  8. 深入理解java虚拟机(二)-----垃圾回收

    做一个java程序员很是幸福,不用管不用的对象如何被回收,但是我认为了解一下也不是坏事. 一.如何判断对象已经死亡? 在进行垃圾回收之前,第一件事肯定是判断对象是否已经死亡.1.引用计数算法给对象添加 ...

  9. 深入理解Java虚拟机二 阅读笔记

    xl_echo编辑整理.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! --- > 以下内容摘抄自 ...

随机推荐

  1. 用HTML5+JS开发跨平台的桌面应用

    通过Node.js和WebKit技术的融合,开发者可以用HTML5技术编写UI,同时又能利用Node.js平台上众多library访问本地OS的能力,最终达到用Web技术就可以编写桌面应用的目的. 选 ...

  2. SAP HANA S4 FI TABLE表结构

    一.统一日记账的表 1)一个行项目表,存储所有应用的全部明细–迅速获得洞察力和扩展能力; 2)次级成本要素也变成了总账科目,统一入口维护和管理; 3)数据只需存储一次在一张表,不需要再做月末对账,如A ...

  3. (原)关于i++和++i的小程序测试

    今天看到一个程序,于是用vs运行了一下,结果出乎我的意料: 代码: ; +(i++))+(+(i++)); i=; +(++i))+(+(++i)); i=; printf("x=%d,y= ...

  4. java+Quartz实现定时任务

    1.首先:导入quartz相关的jar包,这里我用的是maven构建的项目,pom.xml文件导入如下: <dependency> <groupId>org.quartz-sc ...

  5. Spark学习笔记——构建分类模型

    Spark中常见的三种分类模型:线性模型.决策树和朴素贝叶斯模型. 线性模型,简单而且相对容易扩展到非常大的数据集:线性模型又可以分成:1.逻辑回归:2.线性支持向量机 决策树是一个强大的非线性技术, ...

  6. linux 设置中文版man手册

    作为CentOS 新手,看懂英文man固然重要,不过配置好中文man也可以让自己更快速地学习!1. 下载中文man包源码的网址:https://src.fedoraproject.org/repo/p ...

  7. SpringBoot Docker Mysql安装,Docker安装Mysql

    SpringBoot Docker Mysql安装,Docker安装Mysql ================================ ©Copyright 蕃薯耀 2018年4月8日 ht ...

  8. 为你的mail server增加SPF记录

    什么是SPF就是Sender Policy Framework.SPF可以防止别人伪造你来发邮件,是一个反伪造性邮件的解决方案.当你定义了你的domain name的SPF记录之后,接收邮件方会根据你 ...

  9. 【转载】Eclipse 的快捷键以及文档注释、多行注释的快捷键

    一.多行注释快捷键 1.选中你要加注释的区域,用ctrl+shift+C 或者ctrl+/ 会加上//注释2.先把你要注释的东西选中,用shit+ctrl+/ 会加上/*    */注释 3.以上快捷 ...

  10. 十一、K3 WISE 开发插件《VB插件开发如何代码调试 - 步骤讲解》

    =================================== 目录: 1.配置代码调试启动程序kdmain.exe 2.设置断点 3.触发调试 4.变量跟踪 ================ ...