关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JAVA »可视化Java垃圾回收的原理和实现

    可视化Java垃圾回收的原理和实现

    2015-01-19 00:00:00 出处:ImportNew - 进林
    分享

    垃圾回收,就像双陆棋一样,只需几分钟来学习,但要用一生来精通。

    基础

    当谈到释放不再使用的内存,垃圾回收已经在很大程度上取代了早期技术,比如手动内存管理和引用计数。

    这是件好事,因为内存管理令人厌烦,学究式地簿记是计算机擅长的,而不是人擅长的。在这方面,语言的运行时环境比人强。

    现代的垃圾回收非常高效,远远超过早期语言中典型的手工分配。通常,具有其它语言背景的人只盯着垃圾回收造成的中断,却没有完全理解自动内存管理发生作用的上下文环境。

    标记&清除是Java(及其它运行时环境)用于垃圾回收的基本算法。

    在标记&清除算法中,引用会从每个线程栈的桢指向程序的堆。所以,从栈开始,循着指针找到所有可能的引用,然后再循着这些引用递归下去。

    当递归完成,就找到了所有的活对象,其它的都是垃圾。

    请注意,人们经常漏掉的一点是,运行时环境本身也有一个“分配清单(allocation list)”,上面列出了指向每个对象的指针,该列表由垃圾回收器负责维护,并帮助垃圾回收器进行垃圾清理。因此,运行时环境总是可以找出由它创建但尚未回收的对象。

    图一

    上面插图中所示的栈只是一个与单个应用程序线程相关的栈;每个应用程序线程都有一个类似的栈,每个栈本身都有一组指向堆的指针。

    如果垃圾回收器试图在应用程序运行过程中获取活对象的快照,那么它就要追踪运动着的目标,那样很容易漏掉一些严重超时的对象分配,因而无法获得一个准确的快照。因此,“Stop the World”是有必要的;也就是,停止应用程序线程足够长的时间,以便捕获活对象的快照。

    下面是垃圾回收器必须遵循的两条黄金法则:

    垃圾回收器必须回收所有的垃圾。 垃圾回收器必须从不回收任何活对象。

    但这两条规则并不是对等的;如果违反了第二条规则,结果会使数据遭到破坏。

    另一方面,如果违反了第一条规则,则会是另一种情况,系统并不总是能够回收所有的垃圾,但最终会回收所有的垃圾,那么这是可以接受的,而实际上,这是垃圾回收器的基本原理。

    HotSpot

    现在,我们来说下HotSpot,它实际上是一个C、C++以及许多特定于平台的汇编程序组成的混合体。

    当人们想到解释器,就会想到一个很大的while循环,其中包含一个很长的switch语句。但HotSpot解释器比那个要复杂的多(由于性能原因)。在开始阅读JDK源代码的时候,就会发现HotSpot中实在是有许多汇编程序代码。

    对象创建

    Java会预先分配大量的连续空间,就是我们所说的“堆”。之后,HotSpot完全在用户空间里管理这块内存。

    如果一个Java进程占用了大量的系统(或内核)时间,那么毫无疑问,它不是在进行垃圾回收——因为所有的垃圾回收内存“簿记(bookkeeping)”都是在用户空间进行的。

    内存池

    图二

    “永久代(PermGen)”是一个存储区域,用于保存那些需要在程序生存期内一直存活的东西,如类的元数据。不过,随着应用程序服务器的出现,它们有自己的类加载器,并且需要重新加载类的元数据,永久代作为一个优化决策开始显得糟糕,所幸,它在Java 8中消失了。

    Java 8将会使用一个名为“元空间(Metaspace)”的新概念。元空间与永久代并不完全相同。它在堆的外面,由操作系统管理。这意味着,它不会在Java堆中,而是在本地内存里。目前,这还不是一个非常好的消息,因为没有多少工具能够让用户轻松地查看本地内存。所以,永久代消失是件好事,但工具赶上这个变化还需要一些时间。

    Java堆布局

    现在,我们来看下Java堆。注意堆空间之间的虚拟空间。它们提供了一点浮动量,以允许对内存池进行一定量的尺寸调整,又不用为任何对象移动付出代价。

    图三

    “弱代假设(Weak Generational Hypothesis)”

    就现状而言,究竟为什么要将堆分成所有这些内存池?

    图四

    有的运行时事实无法通过静态分析推导出来。上面的插图说明有两组对象:一组存活时间短,一组存活时间长——所以,做额外的簿记以便利用这一事实是有意义的。在Java平台中,有许多类似的作为优化写入平台的事实。

    演示

    Ben Evans进行了一系列的动画演示。第一个演示是个Flash,说明了对象在Eden区和一个新生代Survivor空间之间移动,并最终进入老年代的过程。

    图五是用JavaFX再现了同样的过程。

    图五

    运行时开关

    ‘强制性’参数

    -verbose:gc——为用户输出一些GC信息 -Xloggc:<文件路径>——指定日志输出路径,要确保磁盘有空间 -XX:+PringGCDetails——为辅助工具提供“最低限度信息(Minimum information)”——用这个参数代替-verbose:gc –XX:PrintTenuringDistribution——“过早提升(Premature promotion)”信息

    基本堆大小参数

    -Xms<size> —— 设置预留给堆的最小内存值 -Xmx<size> —— 设置预留给堆的最大内存值 -XX:MaxPermSize=<size>——设置永久代的最大内存值——有利于Spring应用程序和应用服务器

    以前,我们被教导要把-Xms和-Xmx的值设的一样大。不过这已经变了。因此,现在可以为-Xms设置一个合理范围内较小的值,或者根本就不设置,因为堆的适应能力现在已经非常好了。

    其它参数

    -XX:NewRatio=N -XX:NewSize=N -XX:MaxNewSize=N -XX:MaxHeapFreeRatio -XX:MinHeapFreeRatio -XX:SurvivorRatio=N -XX:MaxTenuringThreshold=N

    图六

    为什么要有日志文件

    日志文件的好处是能够用于取证分析,可以使用户免于为了再现问题而不得不再执行一次代码(如果是一个罕见的生产环境错误,那么重现并不容易)。

    另外,它们包含的信息比针对内存的JMX MXBeans所能提供的信息更多,且不说轮询JMX本身会引入一系列GC问题。

    工具

    HP JMeter(用Google查询一下)——免费,非常可靠,但不再提供支持/功能增强 GCViewer——免费,开源,但界面有点丑 GarbageCat——名字最好听 IBM GCMV——支持J9 jClarity Censum——界面最美观,而且最有用——不过,这是我们的偏见!

    小结

    需要了解一些GC基础理论 要让新生代的大部分对象在年轻时死亡 打开GC日志!——原始日志文件难以阅读——使用工具 使用工具来帮助自己调优——测量,而不是猜测
    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    帝国CMS7.5编辑器上传图片取消宽高的三种方法

    帝国cms如何自动生成缩略图的实现方法

    Windows 12即将到来,将彻底改变人机交互

    帝国CMS 7.5忘记登陆账号密码怎么办?可以phpmyadmin中重置管理员密码

    帝国CMS 7.5 后台编辑器换行,修改回车键br换行为p标签

    Windows 11 版本与 Windows 10比较,新功能一览

    Windows 11激活产品密钥收集及专业版激活方法

    如何从 Windows 11 中完全删除/卸载 OneNote?无解!

    抖音安全与信任开放日:揭秘推荐算法,告别单一标签依赖

    ultraedit编辑器打开文件时,总是提示是否转换为DOS格式,如何关闭?

    IT头条

    华为Pura80系列新机预热,余承东力赞其复杂光线下的视频拍摄实力

    01:28

    阿里千问3开源首战告捷:全球下载破千万,国产AI模型崛起新高度!

    01:22

    DeepSeek R1小版本试升级:网友实测编程能力已达到国际一线水平

    23:15

    NVIDIA 与 Dell 合作,大规模交付 Blackwell AI 系统

    20:52

    Cerebras 以最快的 Llama 4 Maverick 性能引领 LLM 推理竞赛

    20:51

    技术热点

    PHP中的随机性——你觉得自己幸运吗?

    搞定Ubuntu Linux下WPA无线上网

    Java使用内存映射实现大文件的上传

    MySQL安全性指南

    MySQL两项性能的基本测试浅谈

    教您使用UniqueIdentifier选取SQL Server主键

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。