版权声明:本文为博主原创文章,未经博主允许不得转载

一.概述

相比起C和C++的自己回收内存,JAVA要方便得多,因为JVM会为我们自动分配内存以及回收内存。

在之前的JVM 之内存管理 中,我们介绍了JVM内存管理的几个区域,其中程序计数器以及虚拟机栈是线程私有的,随线程而灭,故而它是不用考虑垃圾回收的,因为线程结束其内存空间即释放。

而JAVA堆和方法区则不一样,JAVA堆和方法区时存放的是对象的实例信息以及对象的其他信息,这部分是垃圾回收的主要地点。

二.JAVA堆垃圾回收

垃圾回收主要考虑的问题有两个:一个是效率问题,一个是空间碎片问题。

而Java堆中的垃圾回收可以分为两个区域,一个是新生代,一个是老年代。其中新生代又分为一块比较大的Eden空间和两块较小的Survivor空间。因为新生代和老年代所存储的对象群体是不一样的,为了在效率和空间碎片问题中取得平衡,新生代和老年代所使用的垃圾回收算法是不一样。

新生代 -复制算法

从名字上就知道,新生代主要存放的是比较新的对象,回收多次之后仍然存活的对象,就会被送到老年代中区。由此可知新生代的垃圾回收是比较频繁的,所以为解决效率问题,新生代使用了复制算法。复制算法可以将内存分为大小相等的两块,每次分配时使用其中一块,当这一块用完时,就将还存活的对象复制到另一块内存上面区。此时已使用过的这一块内存就可以一次清理掉,这样也不用担心内存碎片的问题。当然这种算法的一个缺点就是内存使用率比较低,只有一半(每次只能一半用来分配出去)。

而IBM公司的研究表明,新生代中的对象98%都是”照生夕死“,所以不需要按照1:1划分,故而会将内存分为一块较大的Eden空间和两块小的Survivor空间。

那么为什么会有两块Survivor呢,复制算法不是只需要一块Eden和一块Survivor就够了吗?

其实这主要还是为了解决碎片化的问题。假设只有一个Survivor区,当Eden区满的时候,进行Gc,存活对象被分配到了Survivor区,清空Eden区。当再一次Gc完成后,存活的对象继续放在Survivor区,这样不是很美好吗,不会有内存碎片啊!但是别忘了,第一次存到Survivor区的对象很可能在第二次Gc的时候就失活了,清理掉Survivor失活对象不就会产生内存碎片了吗?

所以Java堆使用了两个Survivor区,一个from Survivro和一个toSurvivor,第一次Eden满的时候,复制算法将存活对象放到from Survivor区,清空Eden。第二次,Eden满时,将Eden和from Survivor区存活的对象放到to Survivor区,清空Eden和from Survivor,然后重要的一步,将from Survivor和to Survivor角色互换!这样就解决了内存碎片化的问题。

老年代 -标记/整理算法

首先要明白老年代存放的都是会存活得比较久的对象,所以如果老年代也使用复制算法的话,那么复制对象的开销时比较大的,因为老年代的对象基本上都会存活。

标记/整理算法很好理解,主要也就是”标记“,”整理“两个步骤,先将要回收的对象标记,然后让存活对象向着一端移动,最后将边界以外的内存,然后Gc完成。

三.方法区垃圾回收

在某些地方的解释中,方法区也会被叫做“永久代”,与JAVA堆不同,这里存放的是类的信息以及一些常量信息,故而这个区域中被分配的内存一般比较难以被回收,所以才有有”永久代“之名。

虽然方法区中垃圾回收效率较低,但被分配的内存却也并非真的就永不被回收,其主要回收的有两部分内容:废弃常量和无用的类。废弃常量的回收与JAVA堆中类实例回收类似,当常量池中一个常量没有被引用时,就有可能被回收。比如常量池中有一个字符串常量“abc”,当没有任何一个String对象值为"abc"时,那么下一次垃圾回收"abc"常量就有可能会被回收。

而对于无用的类的回收,首先需要判断什么样的类才是”无用的类“:

  • 该类所有的实例都已被回收,即JAVA堆中没有该类的实例。
  • 加载类的ClassLoader已经被回收。
  • 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

虚拟机可能会堆满足这三个条件的”无用的类“进行回收,仅仅是可能,并非必然。


如果觉得对你有帮助,不如花0.5元请作者吃颗糖,让他甜一下吧~~

Java内存管理 -JVM 垃圾回收的更多相关文章

  1. Java内存管理和垃圾回收

    笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...

  2. Java内存管理及垃圾回收总结

    概述 Java和C++的一个很重要的差别在于对内存的管理.Java的自己主动内存管理及垃圾回收技术使得Java程序猿不须要释放废弃对象的内存.从而简化了编程的过程.同一时候也避免了因程序猿的疏漏而导致 ...

  3. java基础(一):谈谈java内存管理与垃圾回收机制

    看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...

  4. java内存管理之垃圾回收及JVM调优

    GC(garbage Collector 垃圾收集器)作用:a.内存的动态分配:b.垃圾回收注:Java所承诺的自动内存管理主要是针对对象内存的回收和对象内存的分配. 一.垃圾标记 程序计数器.Jav ...

  5. Java基础--Java内存管理与垃圾回收

      Java自动内存管理 在讲解内存管理之前,首先需要了解对象和对象引用的区别 对象是类的一个实例,以人这个类为例,Person是我们定义的一个类 public class Person{} publ ...

  6. Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收

    很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...

  7. JVM原理(Java代码编译和执行的整个过程+JVM内存管理及垃圾回收机制)

    转载注明出处: http://blog.csdn.net/cutesource/article/details/5904501 JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.e ...

  8. JVM内存管理及垃圾回收【转】

    很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...

  9. java Vamei快速教程22 内存管理和垃圾回收

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 整个教程中已经不时的出现一些内存管理和垃圾回收的相关知识.这里进行一个小小的总结. ...

随机推荐

  1. 【python小工具】我在bilibili个人资料里控制家里的电脑

    今天在52学习到的,大佬A是在网易云音乐   歌单设置  里,过程没看到,封装一个exe了,可以控制本地cmd命令\ 思路很奇特,想了一下感觉实现应该简单,就打算自己实现一下\ 两步走:网页正则和本地 ...

  2. Ioc及Bean容器(三)

    专题一 IoC 接口及面向接口编程 什么是 IoC Spring 的Bean配置 Bean 的初始化 Spring 的常用注入方式 接口 用于沟通的中介物的抽象化 实体把自己提供给外界的一种抽象化说明 ...

  3. Mybatis数据源

    在描述mybatis数据源之前,先抛出几个问题,这几个问题都能在本文得到解答 1.mybatis是如何获取到mysql连接的? 2.mybatis的Connection是怎么被创建的? 1.Datas ...

  4. 怎么样使用CLion调试分析MySQL Server

    由于在写MySQL日志订阅服务时候,需要确定在什么event之后保存position,所以就开始研究MySQL的源码,刚开始采用最原始的打印输出的方式去调试,然后每次改完编译运行,效率好低,让我很绝望 ...

  5. Deeplearning.ai课程笔记--汇总

    从接触机器学习就了解到Andrew Ng的机器学习课程,后来发现又出来深度学习课程,就开始在网易云课堂上学习deeplearning.ai的课程,Andrew 的课真是的把深入浅出.当然学习这些课程还 ...

  6. 翻译:用户变量(User-Defined Variable)(已提交到MariaDB官方手册)

    本文为mariadb官方手册:User-Defined Variables的译文. 原文:https://mariadb.com/kb/en/user-defined-variables/我提交到Ma ...

  7. Git+Gitlab+Ansible剧本实现一键部署动态网站(二)--技术流ken

    项目前言 之前已经写了一篇关于git和ansible的博客<Git+Gitlab+Ansible剧本实现一键部署Nginx--技术流ken>.关于git,gitliab,ansible在我 ...

  8. Yum搭建LNMP环境(动、静、库分离)(week4_day5)--技术流ken

    前言 本篇博客使用yum来搭建lnmp环境,将采用动态,静态以及数据库分开安装的方式即nginx,php,mysql.会被分开安装在不同的服务器之上,搭建出来一套lnmp环境,并部署wordpress ...

  9. [PHP]算法-最长公共子串的PHP实现

    最长公共子串问题: 给定两个字符串,求出它们之间最长的相同子字符串的长度. 暴力解法思路: 1.以两个字符串的每个字符为开头,往后比较,这样就会需要两层循环 2.两层循环内部的比较方式,也是一层循环, ...

  10. 【Java每日一题】20170119

    20170118问题解析请点击今日问题下方的“[Java每日一题]20170119”查看(问题解析在公众号首发,公众号ID:weknow619) package Jan2017; import jav ...