java垃圾回收机制_干货:Java 垃圾回收机制

什么是自动垃圾回收?

自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制。

所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象;而未使用中的对象(未引用对象),则没有被任何指针给指向,因此占用的内存也可以被回收掉。

在用 C 之类的编程语言时,程序员需要自己手动分配和释放内存。而 Java 不一样,它有垃圾回收器,释放内存由回收器负责。本文接下来将介绍垃圾回收机制的基本过程。

第一步:标记

垃圾回收的第一步是标记。垃圾回收器此时会找出哪些内存在使用中,还有哪些不是。

d9b61212e14e2f3191c979e095504e58.png

上图中,蓝色表示已引用对象,橙色表示未引用对象。垃圾回收器要检查完所有的对象,才能知道哪些有被引用,哪些没。如果系统里所有的对象都要检查,那这一步可能会相当耗时间。关注Java技术栈微信公众号,回复:JVM46,可以获取一份超全 JVM 调优攻略。

第二步:清除

这一步会删掉标记出的未引用对象。

6786b4e22c0e52eeb8cc7e886b5b4f0f.png

内存分配器会保留指向可用内存的引用,以供分配新对象。

压缩

为了提升性能,删除了未引用对象后,还可以将剩下的已引用对象放在一起(压缩),这样就能更简单快捷地分配新对象了。

55ea0e3a5c40d0a74558abef3931c753.png

为什么需要分代垃圾收集?

之前说过,逐一标记和压缩 Java 虚拟机里的所有对象非常低效:分配的对象越多,垃圾回收需时就越久。不过,根据统计,大部分的对象,其实用没多久就不用了。JVM 与 Linux 的内存关系详解,这篇推荐阅读。

来看个例子吧。(下图中,竖轴代表已分配的字节,而横轴代表程序运行时间)

733ecb2d8c17eff962db7b545bdeb724.png

上图可见,存活(没被释放)的对象随运行时间越来越少。而图中左侧的那些峰值,也表明了大部分对象其实都挺短命的。

JVM 分代

根据之前的规律,就可以用来提升 JVM 的效率了。方法是,把堆分成几个部分(就是所谓的分代),分别是新生代、老年代,以及永生代。JVM运行时区域详解,这篇推荐大家看下。

8065fd2d66b4ecba3b7a63f3fcedc955.png

新对象会被分配在新生代内存。一旦新生代内存满了,就会开始对死掉的对象,进行所谓的小型垃圾回收过程。一片新生代内存里,死掉的越多,回收过程就越快;至于那些还活着的对象,此时就会老化,并最终老到进入老年代内存。

0ac9fab95b079e6abde9e8d03eedb397.png

Stop the World 事件 —— 小型垃圾回收属于一种叫 "Stop the World" 的事件。在这种事件发生时,所有的程序线程都要暂停,直到事件完成(比如这里就是完成了所有回收工作)为止。

老年代用来保存长时间存活的对象。通常,设置一个阈值,当达到该年龄时,年轻代对象会被移动到老年代。最终老年代也会被回收。这个事件成为 Major GC。

Major GC 也会触发STW(Stop the World)。通常,Major GC会慢很多,因为它涉及到所有存活对象。所以,对于响应性的应用程序,应该尽量避免Major GC。还要注意,Major GC的STW的时长受年老代垃圾回收器类型的影响。

永久代包含JVM用于描述应用程序中类和方法的元数据。永久代是由JVM在运行时根据应用程序使用的类来填充的。此外,Java SE类库和方法也存储在这里。

如果JVM发现某些类不再需要,并且其他类可能需要空间,则这些类可能会被回收。

世代垃圾收集过程

现在你已经理解了为什么堆被分成不同的代,现在是时候看看这些空间是如何相互作用的。后面的图片将介绍JVM中的对象分配和老化过程。关注Java技术栈微信公众号,回复:JVM46,可以获取一份超全 JVM 调优攻略。

首先,将任何新对象分配给 eden 空间。两个 survivor 空间都是空的。

7c7747b78cb7ee9bcc77f557ab0d06d1.png

当 eden 空间填满时,会触发轻微的垃圾收集。

3129d8d5a8740a683bbb72602f1e2ddb.png

引用的对象被移动到第一个 survivor 空间。清除 eden 空间时,将删除未引用的对象。

73fc6f655f3b92c40d9ca8e00fc791f6.png

在下一次Minor GC中,Eden区也会做同样的操作。删除未被引用的对象,并将被引用的对象移动到Survivor区。然而,这里,他们被移动到了第二个Survivor区(S1)。

此外,第一个Survivor区(S0)中,在上一次Minor GC幸存的对象,会增加年龄,并被移动到S1中。待所有幸存对象都被移动到S1后,S0和Eden区都会被清空。注意,Survivor区中有了不同年龄的对象。

69904d815354b8651eaa7aa605f87dd5.png

在下一次Minor GC中,会重复同样的操作。不过,这一次Survivor区会交换。被引用的对象移动到S0,。幸存的对象增加年龄。Eden区和S1被清空。

712216850c9e3c9dc3234a26be9ea497.png

此幻灯片演示了 promotion。在较小的GC之后,当老化的物体达到一定的年龄阈值(在该示例中为8)时,它们从年轻一代晋升到老一代。

b8e513a3d2021a8cf9f98a8a454b0018.png

随着较小的GC持续发生,物体将继续被推广到老一代空间。

b25406aa759430cf9e64d187f5cebc96.png

所以这几乎涵盖了年轻一代的整个过程。最终,将主要对老一代进行GC,清理并最终压缩该空间。

cfc6dc930ddefbbd98eaab7df4da6e54.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java项目定时任务_java项目定时任务实现

首先配置spring-context.xml文件在xmlns 下加如下代码xmlns:task"http://www.springframework.org/schema/task"在xsi:schemaLocation里添加如下代码http://www.springframework.org/schema/taskhttp://www.springframework.org/schema/task/spring-task-3.1.xsd还有…

enter power save mode解决

这个问题是什么产生的呢?这是我刚来公司的第三天,公司停电,等重新来电的时候有三台电脑都出现了这个问题。连接显示屏没有反应 遇到这种问题,首先这是主机没有正常启动引起的 1第一步:先插拔下电源,重新启动…

python多线程编程_Python 多线程编程

Thread类classThread:def __init__(self,groupNone,targetNone,nameNone,args(),kwargsNone,*,daemonNone)group:None,为日后扩展 ThreadGroup 类实现而保留。target&…

linux修改网卡名(亲测有效)

1查看网卡ip addr 2cd /etc/sysconfig/network-scripts Ls查看 3mv ifcfg-eno16777736 ifcfg-eth0重命名,然后编辑 最后一行加入IPADDR192.168.30.136 NETMASK255.255.255.0 HWADDR00:0C:29:aa?2f BOOTPROTO改成static 4 vi /etc/default/grub 5 grub2-mkconfig…

java 存储空间_Java中的存储空间类型

在Thinking in java里,列举了Java的六种存储类型1.寄存器编写过汇编程序的应该对寄存器非常熟悉,那时候用的ax,bx,cx,dx等等。寄存器在CPU里面,所以速度特别快,但是数量非常有限。在java中无法直…

读取html文件,让其中的内容和notepad打开这个html的样子一样。

然后我写了个python代码,让其读取这个html文件后,内容和这个一样: htmlfopen(13144815898.html,r,encoding"utf-8") htmlconthtmlf.read() print((htmlcont)) 转载于:https://www.cnblogs.com/www-caiyin-com/p/9447285.html

python默认参数举例_Python中的默认参数实例分析

本文研究的主要是Python中的默认参数的相关内容,具体如下。熟悉C语言的可以知道,C语言中的默认参数是写在函数声明中的,为语法糖,与函数的调用无关,是在函数调用的时候由编译器补齐参数然后进行调用。而Python中的默认…

centos安装ipconfig和telnet命令

1我安装的是mini版的 2首先ipconfig查看不到命令 yum -y install net-tools 解决 3在同事的要求下要安装telnet 首先 rpm -qa telnet-server yum -y install telnet-server rpm -qa telnet yum -y install telnet rpa -qa xinetd yum -y install xinetd 测试 netstat -tnl …

java 对象访问权限_Java面向对象编程之访问控制权限

5. 访问控制权限5.1 类型(4个)privatepublicprotected默认权限5.2 作用private : 私有的,只能类内部访问public : 可以在任何位置访问,类内部访问,对象访问protected: 被本类,和本类的子类访问默认权限:可以…

38. 统计一个整数的二进制表示中bit为1的个数

参考: https://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html 转载于:https://www.cnblogs.com/GrimMjxCl/p/9452667.html

python3.7怎么使用arcpy_从Python到空间分析Arcpy|1.3.7 神啊!救救我之如何处理报错...

今天讲的是关键时候不卡壳的技能,尤其是循环语句中和数据清洗中,先假设一种情况,领导安排你把,某机构给你们的坐标x和y数据列表中的每个元素的x偏移3个单位,假设你现在已经可以掌握相关的内容了,心里想太ea…

dockerfile使用(一)

1mkdir dl Cd dl Touch Dockerfile 2修改配置vi Dockerfile FROM alpine:latest MAINTAINER xbf CMD echo ‘hello docker’ 3 docker build -t hello_docker . 4 docker images 5 docker run hello_docker

java程序设计实验报告册_20145215《Java程序设计》实验一实验报告

实验一 Java开发环境的熟悉实验内容及步骤使用JDK编译、运行简单的Java程序命令行下程序开发:在命令行下建立实验目录,进入该目录后创建exp1目录敲入以下代码:package exp1;import java.util.Scanner;public class Hello{public static void …

异步汇合

//多个异步请求完成后汇总结结果(任务执行不区分先后顺序) dispatch_queue_t queue dispatch_get_global_queue(0,0); dispatch_group_t group dispatch_group_create(); dispatch_group_async(group, queue, ^{/*任务a */ }); dispatch_group_async(g…

dockfile应用(二)

1创建目录dl2 Cd dl2 Touch dockerfile Touch index,html 2ROM ubuntu MAINTAINER xbf RUN sed -i ‘s/archive.ubuntu.com/mirrors.ustc.edu.cn/g’ /etc/apt/sources.list RUN apt-get update RUN apt-get install -y nginx COPY index.html /var/www/html ENTRYPOINT [&quo…

python实验九答案_Python实验九

安徽工程大学python程序设计实验报告班级:物流191 姓名:王悦 学号:3190505103 日期:2020.6.16 指导老师:修宇【实验名称】实验九python包管理【实验目的】进一步了解python的计算生态,…

java gb13000_浅谈 GB13000

引言我前几天写了一篇随笔“随机生成常用汉字(再次改进版)”。园友“菜菜灰”评论说“看着太累,不认识的字还是多,代码也很多,几段代码显示2万多汉字”,并给出了相应的 C# 代码:1 System.Text.StringBuilder sb newSy…

元素的移动

我的想法: 1.首先给移动的元素一个绝对定位,position: absolute, 通过top和left来实现元素的移动。 2. 基本过程:(1)当鼠标的左键按下去时,给元素添加onmousemove, onmouseleave(鼠标不在元素上时, 移除onmousemove事件…

python打开csv文件、计算总成绩_实现读取csv文件,文件里面是有限个百分数成绩(99.6、76.8等等...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼实现读取csv文件,文件里面是有限个百分数成绩(99.6、76.8等等)导出GPA 和等级代码是这样,但是报错了,在score float(sc)这行就报错了,下面有没有错误还不知道,大佬能帮看…

json java typeof_Json对象与Json字符串的转化、JSON字符串与Java对象的转换

一.Json对象与Json字符串的转化1.jQuery插件支持的转换方式:$.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象2.浏览器支持的转换方式(Firefox,chrome,opera,safari,ie9&#xff…