概述

内存划分

虚拟机规范中将内存分为六大部分,分别为PC寄存器、JAVA虚拟机栈、JAVA堆、方法区、运行时常量及本地方法栈。

1.PC寄存器:线程独占
2.JAVA虚拟机栈:线程独有;JAVA虚拟机栈是在创建线程的同时创建的,用于存储栈帧,JAVA虚拟机栈也是线程独有的。
3.JAVA堆:全局共享
4.方法区:全局共享;它主要存储的是

  • 运行时常量池
  • 字段信息
  • 方法信息
  • 构造方法
  • 普通函数的字节码内容以及一些特殊方法。
    5.本地方法栈:线程独有,本地方法栈是一个传统的栈,它用来支持native方法的执行。如果JAVA虚拟机是使用的其它语言实现指令集解释器的时候,也会用到本地方法栈。

内存管理

1.一部分是全局共享:

  • JAVA堆
  • 方法区
    2.一部分是线程独有
  • PC寄存器
  • JAVA虚拟机栈
  • 本地方法栈

GC简介及算法

GC策略解决了哪些问题?

内存作为一种有限的资源,然而随着时间的推移内存的垃圾会越来越多。但java并没有提供类似于C/C++这一类内存释放和管理的机制,而是通过内置的GC进行内存的管理。GC的主要工作是:

1.哪些对象可以被回收?
2.何时回收?
3.采用什么样的方式回收?

GC策略采用的何种算法

有一种比较简单直观的办法,它的效率较高,被称作引用计数算法。但是这个算法有一个致命的缺陷,那就是对于循环引用的对象无法进行回收。

根搜索算法(解决哪些对象可以被回收的问题)

由于引用计数算法的缺陷,所以JVM一般会采用一种新的算法,叫做根搜索算法。它的处理方式就是,设立若干种根对象,当任何一个根对象到某一个对象均不可达时,则认为这个对象是可以被回收的。

GC roots(GC根),在JAVA语言中,可以当做GC roots的对象有以下几种:

  • 虚拟机栈中的引用的对象。
  • 方法区中的类静态属性引用的对象。
  • 方法区中的常量引用的对象。(final)
  • 本地方法栈中JNI的引用的对象。
    第一和第四种都是指的方法的本地变量表,第二种表达的意思比较清晰,第三种主要指的是声明为final的常量值。

垃圾收集算法

垃圾搜集的算法主要有三种,分别是标记-清除算法复制算法标记-整理算法。这三种算法都扩充了根搜索算法。

标记-清除算法

当堆中的有效内存空间(available memory)被耗尽的时候,就会停止整个程序(也被成为stop the world),然后进行两项工作,第一项则是标记第二项则是清除

  • 标记:标记的过程其实就是,遍历所有的GC Roots,然后将所有GC Roots可达的对象标记为存活的对象。
  • 清除:清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。

通俗地说也就是当可用内存即将耗尽时,逐步完成以下工作:

  • 1.GC线程就会被触发并将程序暂停;
  • 2.将依旧存活的对象标记起来;
  • 3.将堆中未标记的对象全部清除;
  • 4.程序恢复运行。

缺陷:

  • 1、首先,它的缺点就是效率比较低(递归与全堆对象遍历),而且在进行GC的时候,需要停止应用程序,这会导致用户体验非常差劲
  • 2、第二点主要的缺点,则是这种方式清理出来的空闲内存是不连续的

复制算法

复制算法由“标记-清除算法”基础上演化而来。

复制算法将内存划分为两个区间,在任意一个时间点,所有动态分配的对象只能分配在其中一个区间(活动区间),而另一个区间(空闲区间)则是空闲的。

当可用内存即将耗尽时,会逐步完成以下工作:

  • 1.GC线程就会被触发并将程序暂停;
  • 2.将依旧存活的对象标记起来;
  • 3.将存活对象全部复制到空闲区间,且严格按照内存地址依次排序;
  • 4.将存活对象引用指向新地址;
  • 5.将活动区间转换成空闲区间,并一次性全部回收所有垃圾对象;
  • 6.程序恢复运行。

复制算法弥补了标记-清除算法中内存布局混乱的缺点,但其缺点也很明显:

  • 浪费了一半的内存,也就是说有一半的内存空间是闲置的;
  • 如果对象的存活率很高,我们可以极端一点,假设是100%存活,那么我们需要将所有对象都复制一遍,并将所有引用地址重置一遍。复制这一工作所花费的时间,在对象存活率达到一定程度时,将会变的不可忽视。

复制算法要想使用,最起码对象的存活率要非常低才行,而且最重要的是,我们必须要克服50%内存的浪费。

标记-整理算法

标记-整理算法标记-清除算法类似,可以分成两个阶段:标记和整理

  • 1.标记:它的第一个阶段与标记/清除算法是一模一样的,均是遍历GC Roots,然后将存活的对象标记。
  • 2.整理:移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。因此,第二阶段才称为整理阶段。

优点:标记/整理算法不仅可以弥补标记/清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内存减半的高额代价
缺点:标记/整理算法唯一的缺点就是效率也不高

复制算法、标记/整理算法、标记/清除算法共同点:

  • 1、三个算法都基于根搜索算法去判断一个对象是否应该被回收,而支撑根搜索算法可以正常工作的理论依据,就是语法中变量作用域的相关内容。因此,要想防止内存泄露,最根本的办法就是掌握好变量作用域,而不应该使用前面内存管理杂谈一章中所提到的C/C++式内存管理方式。
  • 2、在GC线程开启时,或者说GC过程开始时,它们都要暂停应用程序(stop the world)。

区别:

  • 效率:复制算法>标记/整理算法>标记/清除算法(此处的效率只是简单的对比时间复杂度,实际情况不一定如此)。
  • 内存整齐度:复制算法=标记/整理算法>标记/清除算法。
  • 内存利用率:标记/整理算法=标记/清除算法>复制算法。

分代搜集算法

没有最好的算法,只有最合适的算法,不同算法适合不同的场景。

  • 新生代或者年轻代【普通GC(minor GC)】:适合使用复制算法
  • 年老代【全局GC(major GC or Full GC)】:采用标记/整理或者标记/清除算法

转载于:https://www.cnblogs.com/rwxwsblog/p/6247255.html

Java内存管理及GC算法相关推荐

  1. java标志清理_JVM内存管理之GC算法精解(五分钟让你彻底明白标记/清除算法)...

    相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内 ...

  2. Java 内存模型及GC原理

    一个优秀Java程序员,必须了解Java内存模型.GC工作原理,以及如何优化GC的性能.与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能 ...

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

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

  4. 【转】Java 内存模型及GC原理

    一个优秀Java程序员,必须了解Java内存模型.GC工作原理,以及如何优化GC的性能.与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能 ...

  5. Java内存管理:深入Java内存区域

    Java内存管理:深入Java内存区域 本文引用自:深入理解Java虚拟机的第2章内容 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述 ...

  6. java内存管理(堆、栈、方法区)

    java内存管理 简介 首先我们要了解我们为什么要学习java虚拟机的内存管理,不是java的gc垃圾回收机制都帮我们释放了内存了吗?但是在写程序的过程中却也往往因为不懂内存管理而造成了一些不容易察觉 ...

  7. java中创建类的时候有没有分配内存,你必须了解的java内存管理机制(一)-内存分配...

    前言 在上一篇文章中,我们花了较大的篇幅去介绍了JVM的运行时数据区,并且重点介绍了栈区的结构及作用,相关内容请猛戳!在本文中,我们将主要介绍对象的创建过程及在堆中的分配方式.from 你必须了解的j ...

  8. java内存管理机制-转载保存有价值的东西

    JAVA 内存管理总结 1. java是如何管理内存的 Java的内存管理就是对象的分配和释放问题.(两部分) 分配 :内存的分配是由程序完成的,程序员需要通过关键字new 为每个对象申请内存空间 ( ...

  9. Java内存管理:Java内存区域 JVM运行时数据区

    Java内存管理:Java内存区域 JVM运行时数据区 在前面的一些文章了解到javac编译的大体过程.Class文件结构.以及JVM字节码指令. 下面我们详细了解Java内存区域:先说明JVM规范定 ...

  10. java 内存例子_简单的例子 关于Java内存管理的讲解

    我想做的是,逐行读取文件,然后用该行的电影名去获取电影信息.因为源文件较大,readlines()不能完全读取所有电影名,所以我们逐行读取. 就这段代码,我想要在位置二处使用base64,然后结果呢? ...

最新文章

  1. 日、德、美、中各国“工业4.0“们的核心差异
  2. DPI — nDPI — Overview
  3. java stringbuilder换行_初遇Java StringBuffer 和 StringBuilder 类利用 StringBuilder 给TextView实现换行处理...
  4. python系统-Python(第八课,简单开发系统)
  5. jquery常用功能
  6. 使用MVCPager做AJAX分页所需要注意的地方
  7. java编程中的持有对方引用是什么意思?有什么作用?
  8. Mybatis SQL 语句中 IF函数不支持
  9. 等级考试(三):三级网络---似曾相识(续)
  10. 【优化算法】量子遗传优化算法(QGA)【含Matlab源码 1123期】
  11. rtx客户端绿化方法+组织架构更新延迟的解决方案
  12. 大数据——海量数据处理的基本方法总结
  13. Unity发布WebGL遇到的问题
  14. Domain Adaptation and Graph Neural Networks
  15. 实体书店不断萎缩 路在何方?
  16. 服务器——SSL/TLS协议信息泄露漏洞(CVE-2016-2183)修复办法
  17. ios开发面试常见问题及答案
  18. “三高“Mysql - Mysql备份概览
  19. 运维开发面试题集锦(25k-35k)
  20. 生病还要被压榨,外包太惨了!

热门文章

  1. spring教程笔记1
  2. DeepLearning tutorial(7)深度学习框架Keras的使用-进阶
  3. 【Caffe安装】ImportError: No module named caffe 的解决方案
  4. mysql 执行时间有波动_阿里P8架构师谈mysql性能优化思路
  5. webstorm运行的端口在哪看_webstorm(10.0.2)的端口号修改
  6. fisco bcos transaction交易结构 源代码位置
  7. 云计算 雾计算 边缘计算的区别
  8. 7723java之战,满江红4之江山美人
  9. 前端----JQuery
  10. java map原理_Java中的HashMap的工作原理是什么?