浅析Java内存区及其垃圾回收机制

本文深入探讨Java的内存管理机制,包括堆和栈的区别,以及两种垃圾判别机制(引用计数和追溯堆栈或静态存储区活引用法)和两种垃圾回收技术(停止-复制和标记-清扫)。此外,还介绍了JVM如何通过自适应和分代的方式提高垃圾回收效率。

浅析Java内存区及其垃圾回收机制

  • Java三大内存区
  • Java堆与栈的形象描述
  • 两种垃圾判别机制
  • 两种垃圾回收技术
  • JIT编译器技术简介

Java三大内存区

Java三大内存区图解

Java堆与栈的形象描述


Java的堆比较特殊,《Java编程思想》(第4版)里把Java的堆(Java的堆是堆,Java的堆栈是栈)比作一个传送带,每分配一个新对象,它就往前移动一格。

但是其实这样的描述不够准确,因为这样的话会造成大量的空间浪费。我们可以设想,如果JVM真的像传送带一样实现堆,那么即使一个对象不在被使用,其存储空间也不会被释放。我们可以这样理解Java的堆:

  • Java里的堆是面向JVM实例的,由运行在此JVM实例上的所有线程共享的,用来存放实例对象(包括数组和new String()方式创造的字符串)的一块内存空间。
  • Java的堆是一种动态内存分配的抽象描述,而不是一种具体的数据结构,其具体实现依赖于具体的Java虚拟机。
  • 由于Java堆的内存管理效率很高,我们可以把Java的堆抽象成一个优化的栈(只有GC能弹出数据的栈)。
    C++的堆无法抽象成栈主要是因为其没有独立于用户程序的垃圾回收机制,每一块分配出去的存储实例对象的内存都要由其自身管理(包括销毁)。这也就是说难以实现对C++堆的整体内存再分配,所以如果把C++的结构抽象为栈这一数据结构的话,那么很难保证C++的堆不会满。而Java则不同了,其具有一个自动的,面向于JVM的垃圾回收机制(相当于MySQL 里的OPTIMIZE TABLE对表的作用);通过GC,那么我们可以利用虚拟机自动实现栈中空间的重新整理,并对Java栈中这些实例对象的引用变量的值进行自动更新(这也是Java引用与c的指针的区别之一)。

  • 同一个调用栈里存放Java方法的栈帧与native方法的栈帧
  • 栈中存放一些基本类型的变量和对象的引用变量。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
  • 栈中的变量可以被多个引用变量连接。比如我们给一个int型变量i赋值1的时候,JVM会在栈中寻找是否有一个值为1的整数,有的话就把这个基本类型内存空间与i关联。与对象引用不同的是,把一个新值赋值给基本变量时,JVM通过改变引用指向的内存空间来改变其值。就是说,如果给i赋值2,那么JVM先查找栈中是否有2,有的话修正引用,而非存储1的那个内存单元;没有的话就把2压栈。
  • 下面说一下两种垃圾判别机制

    引用计数 

    特点描述
    发生时间程序生命周期。
    方式每个对象都有一个引用计数器,当引用离开作用域或被置为null时减一,当对象被连接到一个新引用变量上时,计数器加1。当对象引用计数器为0时,释放对象。
    优点思想简单。
    缺点当出现循环引用的情况时,无法及时回收相关对象;且JVM判断循环引用的开销较大。

    可以使用冒号来定义对齐方式:

    追溯堆栈或静态存储区活引用法
    这种方法,就是从堆栈和静态存储区开始,遍历所有引用,对于发现的每个对象,再遍历此对象所包含的所有引用,反复进行。类似于图的遍历,在这个图里的所有节点(对象)都是活的,剩余的对象就可以被判别为回收了。而且,因为“引用计数”法中的交互引用对象几乎不会在堆栈和静态存储区中(而是随着对象存储在堆中)出现,所以几乎完全避免了这个现象。

    两种垃圾回收技术

    总括 《Java编程思想》(第四版中文版)关于JVM垃圾回收技术的概括:
    自适应的、分代的、停止-复制、标记-清扫的。

    我们先来介绍下停止-复制技术的步骤:
    1. 暂停程序运行(这点看出其不属于后台回收模式);
    2. 将堆中存活的对象从当前堆(或者是当前堆中的块),复制到另一个可用堆(或者是当前堆中可用的块)中;
    3. 原来的堆(块)中就只剩下垃圾,交给GC处理。
    注意:

  • 2中的实现方式依赖于具体的实现;
  • 当原来存活的对象被复制到新堆后,就又是一个接着一个紧密排列的了;
  • 当对象被复制时,其静态存储区和栈中的引用变量会被JVM修正,但是堆中对象里的引用会延迟到被遍历时才会修正(相当于有一张逻辑上存储新旧地址映射关系的表);
  • 当出现只有少量垃圾的情况时,每次都采用停止-复制模式的话,开销太大;
  • 于是,引出了标记-清扫方式
    1. JVM从静态存储区和栈开始遍历所有引用,标记其中所有获得引用;
    2. 之后,标记工作结束时,JVM回收没有被标记的对象。但是,不发生对象复制,所以会节省空间和时间,但并没有起到使对象紧凑排列的作用。

    自适应
    JVM会监视垃圾回收效率,选择并切换这两种方式进行垃圾回收。

    分代
    Java虚拟机的分代比较复杂,可以参考这篇文章

    JIT

    可以参考这篇文章,哈哈!偷个懒,这两个东西要说的太多了!

本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩与纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算与数据处理能力的工具,在图像分析与模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常与其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换与直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构与形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式与Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取与分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术与模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识与实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习与掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值