Java虚拟机的内存管理
众所周知,Java程序员写的代码是没有办法控制Java对象的内存释放的,完全有JVM暗箱操作.
虽然程序员把内存的释放的任务都交给了Java虚拟机,但是并不代表Java程序就不存在内存泄漏.
反而,某程度上,当出现内存泄漏,Debug会变得难度更大.
所以,Java程序员,有必要去了解Java虚拟机对于内存的管理以及垃圾回收的机制.
Java虚拟机是如何判断一个对象可以回收?
当一个对象没有被任何其他所引用时,这个对象被Java虚拟机视为可回收.
早起的虚拟机,使用引用计数的方法判断对象是否可回收.这个方法的好处是简单和效率高,却难以解决循环引用的问题.
现在主流的Java虚拟机都是使用可达性的分析对象是否可回收.从若干Root节点开始遍历,所有从Root节点能到达的对象,都是存活对象.
反之,其他对象就是可回收对象.可以想象,这是有若干个根节点的图,用图论术语就是判断每个节点的可达性.
强引用,软引用,弱引用,虚引用都是什么?
强引用Strong Reference就是平时最常见的,不加任何修饰的对象实例化,得到的都是强引用.
软引用Soft Reference,软引用的对象,当Java虚拟机垃圾回收时出现空间不足的情况,软引用的对象就会被回收.
弱引用Weak Reference,弱引用的对象,当Java虚拟机下一次垃圾回收时,无论如何都会被回收.
虚引用Phantom Reference,虚引用的对象任何一个时刻都不能取得其对象的实例.虚引用的使用在于跟踪对象的生死存亡,当虚引用被垃圾回收时,会收到一个系统通知.
垃圾回收算法都有哪些?
1.标记清除,顾名思义就是标记和清除两个阶段.这个算法的致命弱点是,会产生大量的内存碎片,导致后期即使有足够的内存空间也无法分配大的连续的内存空间.
2.复制算法,是把内存空间分成大小相等的两个区域,每次只使用其中一个区域.每次内存回收,都会把存活的对象复制到另外一个区域.
这个算法虽然解决了内存碎片的问题,但是是以内存缩小原来的一半为代价.
复制算法也常用在新生代的垃圾回收.因为大多数的对象都是朝生夕死的,不会存活过下一轮的垃圾回收.所以实际上并没有必要按照1:1的比例来划分内存空间.
现实情况,内存被划分为一个较大的eden区和两个较小的survivor区.HotSpot虚拟机的eden:survivor:survivor=8:1:1.
每次都会使用eden和其中一个survivor用来分配内存,当垃圾回收时会把存活的对象复制到另外一个survivor区.
当出现survivor的内存不足时,会动用老年代的内存空间.老年代起的是一个担保的作用.
3.标记整理算法.把存活的对象都标记出来,再移动到内存空间的一端,把端边界以外的内存空间都清除释放.老年代一般采用标记整理算法.
4.分代收集算法.一般把内存空间分成老年代和新生代,不同的区域根据对象存活的周期和特点,使用合适的垃圾回收算法.
新生代使用复制算法.老年代使用标记清除或者标记整理算法.
Java程序会在什么时候执行垃圾回收呢?
答案是,安全区域(Safe Region),指在一端代码片段之中,引用关系不会发生变化,在这个区域任意地方开始垃圾回收都是安全的.
当线程执行到安全区域时,会首先标识自己已经进入了安全区域.
当线程要离开安全区域时,它要检查系统是否已经完成了根节点枚举(或整个垃圾回收过程),如果完成那线程就继续执行,否则必须等到可以离开安全区域的信号为止.
让所有执行线程都停顿下来到达最近的安全区域,有两种方案:
1.抢占式中断(Preemptive Suspension).在垃圾回收发生时,首先把所有线程都全部中断,没有到达安全区域的线程,就恢复线程让它运行到最近的安全区域上.
现在,几乎没有Java虚拟机是使用抢占式中断,来暂停所有线程从而执行垃圾回收.
2.主动式中断(Voluntary Suspension).当准备执行垃圾回收时,会设置一个标志位,表示要开始垃圾回收了.所有线程都会在安全区域处轮询这个标志位.
当发现这个标志位被设置后,线程会暂停自己.
Java虚拟机的内存管理的更多相关文章
- 深入java虚拟机学习 -- 内存管理机制
前面说过了类的加载机制,里面讲到了类的初始化中时用到了一部分内存管理的知识,这里让我们来看下Java虚拟机是如何管理内存的. 先让我们来看张图 有些文章中对线程隔离区还称之为线程独占区,其实是一个意思 ...
- java虚拟机(一)——内存管理机制与OOM异常
一 java内存区域与内存溢出异常(OOM) 1)运行时数据区域划分 1.程序计数器(Program Conuter Register) 程序计数器是一块较小的内存空间,它是当前线程执 ...
- 深入了解Java虚拟机和内存管理
1.java程序的执行过程 java源文件->解析器->class文件->java类加载器->java运行时数据区->执行引擎 2.我们接下来看一下java运行 ...
- [深入理解Java虚拟机]<自动内存管理>
Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就 ...
- 深入理解JAVA虚拟机 自动内存管理机制
运行时数据区域 其中右侧三个一起的部分是每个线程一份,左侧两个是所有线程共享的. 程序计数器(Program Counter Register) 英文名称叫Program Counter Regist ...
- Java虚拟机理解-内存管理
运行时数据区域 jdk 1.8之前与之后的内存模型有差异,方法区有变化(https://cloud.tencent.com/developer/article/1470519). java的内存数据区 ...
- 深入理解java虚拟机,内存管理部分
1,对象回收前会调用finalize()方法,尝试自救,只能调用一次 2,上面横向对比c++的析构函数,但是java有良好的内存管理,而且try/catch做得比较好 3,回收一个常量,1,对象的实例 ...
- Java虚拟机的内存管理----垃圾收集器
1.Serial收集器 优点,是简单而高效,单线程避免了线程交互的开销. 缺点,进行垃圾回收时需要Stop the world(暂停所有用户线程). 2.ParNew收集器 它是Serial收集器的多 ...
- Java虚拟机之内存区域
原创文章,转载请标明出处! 目录 一.背景 二.运行时内存区域概述 1.官方描述 2.中文翻译 3.内存区域简述 4.运行时数据区简图 5.运行时数据区详图 三.JVM线程 JVM数据区域与线程关系 ...
随机推荐
- WPF DataGrid使用简介
1)自动生成列 <DataGrid AutoGenerateColumns="True" Name="datagrid" CanUserAddRows=& ...
- 【LG5021】[NOIP2018]赛道修建
[LG5021][NOIP2018]赛道修建 题面 洛谷 题解 NOIP之前做过增强版还没做出来\(QAQ\) 一看到题目中的最大值最小,就很容易想到二分答案 重点是考虑如何\(check\) 设\( ...
- spark读取mongodb数据写入hive表中
一 环境: spark-: hive-; scala-; hadoop--cdh-; jdk-1.8; mongodb-2.4.10; 二.数据情况: MongoDB数据格式{ "_i ...
- idea 严重: Error configuring application listener of class org.springframework.web.context.Context 后面省略
根本原因:jar文件没有同步发布到自己项目的lib目录中 解决方案:把之前在这个位置的jar文件,put into 到 /WEB-INF/lib 目录下即可
- 《Flutter实战》开源电子书
<Flutter实战>开源电子书 <Flutter实战> 开源了,本书为 Flutter中文网开源电子书项目,本书系统介绍了Flutter技术的各个方面,本书属于原创书籍(并非 ...
- equals和==方法比较(一)
问题描述 今天在使用spotbugs代码走查时发现这样一个问题,两个Long类型的变量使用==判断数值是否相等,spotbugs提示这是一个很致命的错误,代码大概如下, Long l1=123l; L ...
- XAF-如何改变列表点击时的默认行为
在 Windows 窗体应用程序中,按下回车或双击列表会打开默认的详细视图. 在 ASP.NET Web 应用程序中,单击对象时执行此操作. 这一行为是由 ListViewProcessCurrent ...
- C#Framework4.0支持异步async/await语法
由于用户使用的是XP系统,但是程序里异步都是通过async/await代码来实现的,然而async/await需要Framework4.5版本才可以,而XP系统最高只能支持到Framework4.0, ...
- springmvc传参---LocalDateTime、Date等时间类型转换
此处定义的dateConvert用来转换Date类型,如果是LocalDate.LocalDateTime类型,则将Date类型换成相应的类型即可,注意java8的日期类型需要用Formatter格式 ...
- Java EE JSP编程基础
一.JSP编程介绍 JSP是实现普通静态HTML和动态HTML混合编码的技术,可以说是Servlet的一种变形,相比Servlet它更像普通的Web页面.JSP在第一次运行时会花费很长时间,原因在与其 ...