JAVA垃圾收集器之Parallel Scavenge收集器

ParallelScavenge收集器是JAVA虚拟机中专注于吞吐量优化的垃圾收集器,适用于后台运算密集型任务。其核心特性包括自适应调节策略,以实现最优的垃圾收集效果。

Parallel Scavenge收集器是JAVA虚拟机中垃圾收集器的一种。和ParNew收集器类似,是一个新生代收集器。使用复制算法的并行多线程收集器。

1、特点

Parallel Scavenge收集器的关注点与其他收集器不同, ParallelScavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间),虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。

由于与吞吐量关系密切,Parallel Scavenge收集器也经常被称为“吞吐量优先”收集器。

       该垃圾收集器,是JAVA虚拟机在Server模式下的默认值,使用Server模式后,java虚拟机使用Parallel Scavenge收集器(新生代)+ Serial Old收集器(老年代)的收集器组合进行内存回收。

2、使用场景

主要适应主要适合在后台运算而不需要太多交互的任务。

比如需要与用户交互的程序,良好的响应速度能提升用户的体验;而高吞吐量则可以最高效率地利用CPU时间,尽快地完成程序的运算任务等。

3、重要参数

重要的参数有三个,其中两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数及直接设置吞吐量大小的 -XX:GCTimeRatio参数。另外一个是UseAdaptiveSizePolicy开关参数。

MaxGCPauseMillis参数允许的值是一个大于0的毫秒数,收集器将尽力保证内存回收花费的时间不超过设定值。不过大家不要异想天开地认为如果把这个参数的值设置得稍小一点就能使得系统的垃圾收集速度变得更快,GC停顿时间缩短是以牺牲吞吐量和新生代空间来换取的:系统把新生代调小一些,收集300MB新生代肯定比收集500MB快吧,这也直接导致垃圾收集发生得更频繁一些,原来10秒收集一次、每次停顿100毫秒,现在变成5秒收集一次、每次停顿70毫秒。停顿时间的确在下降,但吞吐量也降下来了。

 

GCTimeRatio参数的值应当是一个大于0小于100的整数,也就是垃圾收集时间占总时间的比率,相当于是吞吐量的倒数。如果把此参数设置为19,那允许的最大GC时间就占总时间的5%(即1 /(1+19)),默认值为99,就是允许最大1%(即1 /(1+99))的垃圾收集时间。

-XX:+UseAdaptiveSizePolicy是一个开关参数,当这个参数打开之后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics)。

4、自适应调节策略

Parallel Scavenge收集器能够配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成。只需要把基本的内存数据设置好(如-Xmx设置最大堆),然后使用MaxGCPauseMillis参数(更关注最大停顿时间)或GCTimeRatio参数(更关注吞吐量)给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了。自适应调节策略也是Parallel Scavenge收集器与ParNew收集器的一个重要区别。

5、具体使用示例

源代码

package com.gc;

 

import java.util.ArrayList;

import java.util.List;

 

/**

 * 简单的JAVA虚拟机内存回收,Parallel Scavenge收集器的使用

 * 运行参数,见具体方法,注意:需要开启server模式才能使用

 * @author 范芳铭

 */

public class EasyParallelScavenge {

       public byte[] placeHolder =new byte[64 * 1024]; //占位符

       public static voidmain(String[] args) throws Exception{

              outOfMemoryByExpansionSize();

       }

      

      

       /**

        * JAVA虚拟机的大小适当可扩展,其中Xms30m,Xmx400m

        * 参数:-server -Xms30m-Xmx100m -XX:+UseParallelGC -XX:+PrintGCDetails

        * @author 范芳铭

        */

       private static voidoutOfMemoryByExpansionSize() throws Exception{

              List<EasyParallelScavenge>list = new ArrayList<EasyParallelScavenge>();

              while(true){

                     EasyParallelScavengeserial = new EasyParallelScavenge();

                     list.add(serial);

                     Thread.sleep(10);//停顿10毫秒

              }

       }

}

参数说明:

-server  服务器模式运行

-Xms30m  最小JAVA虚拟机内存30M

-Xmx100m最大JAVA虚拟机内存100M

-XX:+UseParallelGC   明确指定使用Parallel Scavenge收集器

-XX:+PrintGCDetails 打印回收情况

 

运行结果如下:

…[GC [PSYoungGen: 7449K->3728K(7552K)] 66980K->66980K(75136K),0.0022792 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7443K->3728K(7552K)] 70695K->70715K(75136K), 0.0027722 secs] [Times:user=0.00 sys=0.03, real=0.00 secs]

[Full GC [PSYoungGen:3728K->3136K(7552K)] [PSOldGen: 66986K->67563K(76928K)]70715K->70700K(84480K) [PSPermGen: 2088K->2088K(16384K)], 0.0038774 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [PSYoungGen: 3714K->3744K(7552K)]71278K->71308K(84480K), 0.0017028 secs] [Times: user=0.00 sys=0.00,real=0.00 secs]

[GC [PSYoungGen:7459K->3744K(7552K)] 75023K->75025K(84480K), 0.0027427 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

[GC [PSYoungGen: 7459K->3744K(7552K)]78739K->78753K(84480K), 0.0048844 secs] [Times: user=0.03 sys=0.00,real=0.01 secs]

[Full GC [PSYoungGen:3744K->1728K(7552K)] [PSOldGen: 75009K->76922K(87488K)]78753K->78651K(95040K) [PSPermGen: 2088K->2088K(16384K)], 0.0107597 secs][Times: user=0.00 sys=0.00, real=0.01 secs]

[GC [PSYoungGen:3714K->3744K(7552K)] 80637K->80667K(95040K), 0.0015904 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7459K->3728K(7552K)] 84382K->84372K(95040K), 0.0028244 secs] [Times:user=0.03 sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7443K->3728K(7552K)] 88087K->88093K(95040K), 0.0023412 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:3728K->640K(7552K)] [PSOldGen: 84364K->87438K(91072K)]88093K->88078K(98624K) [PSPermGen: 2088K->2088K(16384K)], 0.0048474 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:3714K->128K(7552K)] [PSOldGen: 87438K->91023K(91072K)]91153K->91151K(98624K) [PSPermGen: 2088K->2088K(16384K)], 0.0047349 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:3714K->3714K(7552K)] [PSOldGen: 91023K->91023K(91072K)]94738K->94738K(98624K) [PSPermGen: 2088K->2088K(16384K)], 0.0031963 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen: 3714K->3649K(7552K)][PSOldGen: 91023K->91070K(91072K)] 94738K->94720K(98624K) [PSPermGen:2088K->2087K(16384K)], 0.0209529 secs] [Times: user=0.03 sys=0.00, real=0.02secs]

[Full GC [PSYoungGen:3713K->3713K(7552K)] [PSOldGen: 91070K->91070K(91072K)] 94784K->94784K(98624K)[PSPermGen: 2087K->2087K(16384K)], 0.0035128 secs] [Times: user=0.02sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:3713K->3713K(7552K)] [PSOldGen: 91070K->91070K(91072K)]94784K->94784K(98624K) [PSPermGen: 2087K->2087K(16384K)], 0.0027033 secs][Times: user=0.00 sys=0.00, real=0.00 secs]

Exception in thread "main"java.lang.OutOfMemoryError: Java heap space

    atcom.gc.EasyParNew.<init>(EasyParNew.java:12)

    atcom.gc.EasyParNew.outOfMemoryByExpansionSize(EasyParNew.java:39)

    atcom.gc.EasyParNew.main(EasyParNew.java:14)

Heap

 PSYoungGen     total 7552K, used 3776K [0x0e4b0000, 0x0efc0000, 0x0efc0000)

 eden space 3776K, 100% used [0x0e4b0000,0x0e860000,0x0e860000)

 from space 3776K, 0% used [0x0ec10000,0x0ec10000,0x0efc0000)

 to   space 3776K, 0% used[0x0e860000,0x0e860000,0x0ec10000)

 PSOldGen       total 91072K, used 91070K [0x08bc0000, 0x0e4b0000, 0x0e4b0000)

  object space 91072K, 99% used[0x08bc0000,0x0e4af980,0x0e4b0000)

 

6、和serial、parNew两种新生代收集器的简单区别

[GC [DefNew: 1986K->128K(2112K),0.0011191 secs] 27809K->27808K(30528K), 0.0011425 secs] [Times: user=0.00sys=0.01, real=0.00 secs]

[GC [ParNew: 1990K->132K(2112K),0.0007742 secs] 24112K->24110K(30528K), 0.0007964 secs] [Times: user=0.00sys=0.00, real=0.00 secs]

[GC [PSYoungGen:7449K->3728K(7552K)] 66980K->66980K(75136K), 0.0022792 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

GC[ParNew 表示使用的是parNew收集器。

GC[DefNew 表示用的是serial收集器。

[GC[PSYoungGen 表示用的是Parallel Scavenge收集器。
---------------------
作者:阿饭同学
来源:优快云
原文:https://blog.youkuaiyun.com/ffm83/article/details/42872661
版权声明:本文为博主原创文章,转载请附上博文链接!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值