记一次摸不着头脑的FullGC问题 (Thumbnails压缩图片占用巨大内存)

使用thumbnailator导致OOM问题 使用thumbnailator导致OOM问题 thumbnailator 最近项目需要用户上传个人的图片以便于考勤打卡,但是考虑到用户上传的图片可能比较大,所以使用了thumbnailator进行压缩处理,日常测试时未发现任何问题,但是上线之后导致了OOM,经过排查发现是用thumbnailator进行压缩时,消耗的内存太高,虽然上传之后能够快速的释放内存,但是在并发的情况下,内存的消耗达到顶峰,... 阅读详情
AI摘要

本文详细分析了一次由图片压缩过程引起的JVM内存占用异常问题,通过对比不同图片处理库的内存消耗,定位并解决了内存飙升的问题。

问题现象

首先用户反映,有数据不一致情况产生,为了查询什么原因导致的数据不一致问题,
扒拉出来日志看了一通,发现有个简单的查询耗时特别长,平时只要几ms返回结果的
确调用了200多s,查了各个服务的日志,发现并没有什么问题,把日志展开了看,发现
有5分钟时间,系统各种超时,各种错误,包括连接数据库超时,连接redis超时,等等
就考虑看一下GC日志,这一看不要紧,发现这5分钟时间GC日志刷了上千条FullGC,如下图所示:
在这里插入图片描述
回收前后内存变化不大,基本没回收掉内存,但还在不断的回收,因为使用的CMS内存回收器,超过最大内存的80%时会进行FullGC,所以JVM一直在傻傻的回收内存空间,应用程序几乎暂停。

好了,基本找到为什么会报错了,但是为什么会频繁的FullGC呢,这个问题又困扰了很久

分布式系统数据不一致
找系统报错
没啥问题
时间段内大量超时
查看GC日志
大量FullGC

思考可能是内存泄漏,或者是某个远程接口阻塞导致大量请求堆积,查看代码发现,代码中resttemplate设置的超时时间都是60s超时,而整个GC持续了5分钟,如果内存泄漏,内存会一直不回收,最终导致的结果是内存占满,OutOfMemoryError, 但是这个摸不着头脑的FullGC最终把内存回收掉了,所以应该不是内存泄漏导致的。
猜想可能是某个业务占用内存特别大,并且短时间内回收不掉。

查阅了好久的代码以及日志,最终定位到一段图片压缩的代码,原代码如下:

import net.coobird.thumbnailator.Thumbnails;
public class ImageProcessor {
	  /**
	   * 压缩图片 bytes -> bytes
	   * @param imageContent image bytes
	   * @param size 压缩尺寸
	   * @return resized bytes
	   * @throws IOException e
	   */
	static byte[] resize(byte[] imageContent, int size) throws IOException {
	
	    ByteArrayOutputStream out = new ByteArrayOutputStream();
	
	    Thumbnails.of(new ByteArrayInputStream(imageContent)).size(size, size).useExifOrientation(true).outputFormat(FileTypeUtil.JPG).toOutputStream(out);
	
	    return out.toByteArray();
	 }
}

最开始以为是ByteArrayOutputStream流没关闭造成的,查看了ByteArrayOutputStream的源码:

/**
     * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
     * this class can be called after the stream has been closed without
     * generating an <tt>IOException</tt>.
     */
    public void close() throws IOException {
    }

close方法不做任何的操作,因为这个是纯内存操作的流,没有跟文件系统打交道,这个地方数据量不需要关闭,用完等待垃圾回收就可以了。
既然不是这里的问题,那我对这个方法做个测试吧,使用了如下的方法打印了内存占用情况:

private static void getFreeMemoryPercentage() {
    // 虚拟机级内存情况查询
    long vmFree = 0;
    long vmUse = 0;
    long vmTotal = 0;
    long vmMax = 0;
    int byteToMb = 1024 * 1024;
    Runtime rt = Runtime.getRuntime();
    vmTotal = rt.totalMemory() / byteToMb;
    vmFree = rt.freeMemory() / byteToMb;
    vmMax = rt.maxMemory() / byteToMb;
    vmUse = vmTotal - vmFree;
    System.out.println("JVM内存已用的空间为:" + vmUse + " MB");
    System.out.println("JVM内存的空闲空间为:" + vmFree + " MB");
    System.out.println("JVM总内存空间为:" + vmTotal + " MB");
    System.out.println("JVM总内存空间为:" + vmMax + " MB");

    System.out.println("======================================");
    // 操作系统级内存情况查询
    OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    String os = System.getProperty("os.name");
    long physicalFree = osmxb.getFreePhysicalMemorySize() / byteToMb;
    long physicalTotal = osmxb.getTotalPhysicalMemorySize() / byteToMb;
    long physicalUse = physicalTotal - physicalFree;
    System.out.println("操作系统的版本:" + os);
    System.out.println("操作系统物理内存已用的空间为:" + physicalFree + " MB");
    System.out.println("操作系统物理内存的空闲空间为:" + physicalUse + " MB");
    System.out.println("操作系统总物理内存:" + physicalTotal + " MB");

    // 获得线程总数
    ThreadGroup parentThread;
    int totalThread = 0;
    for (parentThread = Thread.currentThread().getThreadGroup(); parentThread
        .getParent() != null; parentThread = parentThread.getParent()) {
      totalThread = parentThread.activeCount();
    }
    System.out.println("获得线程总数:" + totalThread);

  }

main方法如下:

   public static void main(String[] args) throws IOException {
    byte[] b = Files.readAllBytes(Paths.get("C:\\Users\\zhangwb\\Desktop\\微信图片_20200717174522.png"));
    getFreeMemoryPercentage();
    System.out.println("压缩前大小:" + b.length);
    byte[] a = resize(b, 1920);
    getFreeMemoryPercentage();
    System.out.println("压缩后大小:" + a.length);

  }

执行这个方法打印出来的日志如下:

JVM内存已用的空间为:22 MB
JVM内存的空闲空间为:223 MB
JVM总内存空间为:245 MB
JVM总内存空间为:3616 MB
======================================
操作系统的版本:Windows 10
操作系统物理内存已用的空间为:2538 MB
操作系统物理内存的空闲空间为:13730 MB
操作系统总物理内存:16268 MB
获得线程总数:2
压缩前大小:11398750
JVM内存已用的空间为:423 MB
JVM内存的空闲空间为:228 MB
JVM总内存空间为:651 MB
JVM总内存空间为:3616 MB
======================================
操作系统的版本:Windows 10
操作系统物理内存已用的空间为:2640 MB
操作系统物理内存的空闲空间为:13628 MB
操作系统总物理内存:16268 MB
获得线程总数:2
压缩后大小:255408

可以看到读出来的数据内存占用22M,图片压缩后JVM内存飙升到423M,多了将近20倍!!
图片压缩后大小小了不少,但是内存却多了这么多,这个可能是导致内存飙升,并且一直FullGC的真正元凶。

终于找到问题了,那如何解决呢

替换掉图片压缩的方法,改用GraphicsMagick处理图片,修改完之后的代码如下:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;

/**
 * @author prague
 * @description 使用GraphicsMagick处理图片
 */
@Slf4j
public class GmImageProcessor {

  /**
   * 临时文件前缀-原始文件
   */
  public static final String SOURCE_PREFIX = "imgCut";
  /**
   * 临时文件前缀-转换文件
   */
  public static final String TARGET_PREFIX = "imgCutResult";
  /**
   * 所有输出文件都指定为JPEG
   */
  private static final String TARGET_IMG_SUFFIX = ".jpg";
  public static byte[] resize(byte[] imageContent, int size) throws IOException {

    Path sourcePath = null;
    Path targetPath = null;

    try {

      sourcePath = loadFile(imageContent);
      IMOperation op = new IMOperation();

      targetPath = Files.createTempFile(TARGET_PREFIX, TARGET_IMG_SUFFIX);

      op.size(size, size);
      op.addImage(sourcePath.toAbsolutePath().toString());
      op.resize(size, size, ">");
      op.p_profile("*");
      op.addImage(targetPath.toAbsolutePath().toString());

      log.debug("输出文件路径:{}", targetPath);

      ConvertCmd convertCmd = new ConvertCmd(true);
      convertCmd.run(op);

      return Files.readAllBytes(targetPath);
    } catch (Exception e) {
      log.error("压缩图片异常", e);
    } finally {
      deleteFile(sourcePath);
      deleteFile(targetPath);
    }

    return null;
  }

  /**
   * 旋转图
   *
   * @param degree 逆时针
   */
  static byte[] rotateImage(byte[] imageContent, int degree) {
    Path sourcePath = null;
    Path targetPath = null;
    try {
      sourcePath = loadFile(imageContent);
      IMOperation op = new IMOperation();
      //2020-07-28 16:13:06 add by gaotx 兼容瑞琪逆时针度数
      op.rotate((double) degree);
      op.addImage(sourcePath.toAbsolutePath().toString());
      targetPath = Files.createTempFile("imgCutResult", TARGET_IMG_SUFFIX);
      log.debug("输出文件路径:{}", targetPath);
      op.addImage(targetPath.toAbsolutePath().toString());
      ConvertCmd cmd = new ConvertCmd(true);
      log.debug(op.toString());
      cmd.run(op);
      return Files.readAllBytes(targetPath);
    } catch (Exception e) {
      BusiExceptionUtils.marshException(e);
    } finally {
      deleteFile(sourcePath);
      deleteFile(targetPath);
    }
    return null;
  }

  /**
   * 把一张大图切成多张小图,期间要保持源文件,完成后删除源文件, 每次切图完成后,删除临时目标文件
   */
  static byte[] cut(Path sourcePath, int startX, int startY, int endX, int endY, int degree) {

    Path outPath = null;
    try {
      IMOperation op = new IMOperation();
      op.addImage(sourcePath.toAbsolutePath().toString());
      int width = NumberUtils.max(endX - startX, 0);
      int height = NumberUtils.max(endY - startY, 0);
      op.crop(width, height, startX, startY);
      if (degree != 0) {
        //2020-07-28 16:13:06 add by gaotx 兼容瑞琪逆时针度数
        op.rotate((double) degree);
      }
      outPath = Files.createTempFile(TARGET_PREFIX, FileTypeUtil.JPG);
      log.debug("输出文件路径:{}", outPath);
      op.addImage(outPath.toAbsolutePath().toString());
      ConvertCmd convert = new ConvertCmd(true);
      log.debug(op.toString());
      convert.run(op);
      return Files.readAllBytes(outPath);
    } catch (Exception e) {
    	// TODO 处理异常
    } finally {
      deleteFile(outPath);
    }
    return null;
  }


  /**
   * bytes -> path
   *
   * @param imageContent bytes
   * @return path
   */
  static Path loadFile(byte[] imageContent) {
    Path sourcePath = null;
    String suffix = "." + bytes(imageContent);
    try {
      sourcePath = Files.createTempFile(SOURCE_PREFIX, suffix);
      log.debug("当前临时文件路径={}", sourcePath);
      Files.write(sourcePath, imageContent);
    } catch (IOException e) {
      log.error(e.getMessage(), e);
    }
    return sourcePath;
  }
/**
   * byte数组转换成16进制字符串
   */
  public static String bytes(byte[] src) {
    StringBuilder stringBuilder = new StringBuilder();
    if (src == null || src.length <= 0) {
      return null;
    }
    // 防止调用的时候没有进行截取前几位
    if (src.length > 4) {
      src = Arrays.copyOfRange(src, 0, 4);
    }

    for (byte b : src) {
      // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写
      String hv = Integer.toHexString(b & 0xFF).toUpperCase();
      if (hv.length() < 2) {
        stringBuilder.append(0);
      }
      stringBuilder.append(hv);
    }
    return getFileType(stringBuilder.toString());
  }

  /**
   * 根据文件路径获取文件头信息,因为根据文件的后缀名识别文件类型并不准确 424D--->BMP (bmp) ,  FFD8FF--->JPEG (jpg) , 89504E47---> PNG
   * (png)
   *
   * @return 文件头信息
   */
  public static String getFileType(String bytes) {
    if (bytes != null) {
      if (bytes.contains("FFD8FF")) {
        return "jpg";
      }
      if (bytes.contains("89504E47")) {
        return "png";
      }
      if (bytes.contains("424D")) {
        return "bmp";
      }
      if (bytes.contains("25504446")) {
        return "pdf";
      }
    }
    return null;
  }
  /**
   * 删除文件
   *
   * @param imagePath imagePath
   */
  static void deleteFile(Path imagePath) {
    try {
      if (imagePath != null) {
        Files.deleteIfExists(imagePath);
      }
      log.info("临时文件清理成功");
    } catch (IOException e) {
      log.error(e.getMessage(), e);
    }
  }

}

windows系统调试需要下载安装http://www.graphicsmagick.org/,linux环境请自行百度,并且在代码中设置path:
convertCmd.setSearchPath(“C:\Program Files\GraphicsMagick-1.3.35-Q16”);

否则调用会报找不到gm文件的异常
ok,我们对同样的图片进行同样大小的压缩,得出内存占用情况如下:

JVM内存已用的空间为:22 MB
JVM内存的空闲空间为:223 MB
JVM总内存空间为:245 MB
JVM总内存空间为:3616 MB
======================================
操作系统的版本:Windows 10
操作系统物理内存已用的空间为:2762 MB
操作系统物理内存的空闲空间为:13506 MB
操作系统总物理内存:16268 MB
获得线程总数:2
压缩前大小:11398750
14:16:10.583 [main] DEBUG com.yonyou.einvoice.common.util.image.GmImageProcessor - 当前临时文件路径=C:\Users\zhangwb\AppData\Local\Temp\imgCut742249801216682093.png
14:16:10.625 [main] DEBUG com.yonyou.einvoice.common.util.image.GmImageProcessor - 输出文件路径:C:\Users\zhangwb\AppData\Local\Temp\imgCutResult2449445347052121528.jpg
14:16:16.003 [main] INFO com.yonyou.einvoice.common.util.image.GmImageProcessor - 临时文件清理成功
14:16:16.004 [main] INFO com.yonyou.einvoice.common.util.image.GmImageProcessor - 临时文件清理成功
JVM内存已用的空间为:29 MB
JVM内存的空闲空间为:216 MB
JVM总内存空间为:245 MB
JVM总内存空间为:3616 MB
======================================
操作系统的版本:Windows 10
操作系统物理内存已用的空间为:2665 MB
操作系统物理内存的空闲空间为:13603 MB
操作系统总物理内存:16268 MB
获得线程总数:2
压缩后大小:209797

可以看出,图片压缩的更小了,JVM内存基本没有占用,堆外内存也基本没占用。

缺点:需要在服务器上安装插件,如果是私有部署比较麻烦,需要安装人员安装插件,否则图片压缩报错。

上线后就没再出现过内存占用暴增的情况了。

思考:你所看到的错误,并不一定是真正的错误,特别是超时的错误,有可能是其它原因导致的应用暂停,比如频繁的FullGC,比如,线程栈出现的死锁等问题。一定要找到真正的问题,并且经过自己验证过的,所有问题都不是凭空产生的,一定是有原因的,可以使用科学的知识解释的。

图片过大引起的内存溢出解决方案 使用BitmapFactory加载图片时,如果图片过大可能引起OutOfmemory溢出的问题。解决办法。 立即下载

相关推荐

图片压缩类

图片压缩

java 校验文件头 判断虚假文件

/**      * 图片文件与视频文件检查      * @param imgname      * @param InputStream      * @param filename      * @return      */     public String checkImage(InputStream is, String filename) {         //创

awhip9的博客 2450

Thumbnails图片处理压缩/裁剪java代码纯净示例+注释详细

使用Thumbnails插件实现对图片的压缩、裁剪、旋转、水印等。 导入项目后修改图片地址和输出图片地址,运行main方法即可看到效果。

记一次图片压缩内存溢出的问题

记一次遇见的问题: 起因:Web应用在后台需要展示许多图片,于是页面出现卡顿甚至失去连接。一次性需要加载出60多张1.6M图片。 查看的文章: 1、前端|加载的图片太多或者太大怎么办(上) 2、java大图片内存溢出问题解决办法 3、java使用google开源工具实现图片压缩 4、使用Thumbnails实现图片指定大小压缩 5、Intellij IDEA 的Tomcat Server 配置VM options参数说明 了解:图片上传,硬盘的存放空间不值钱,但是网速太值钱了,用户加载半天,

Drollwanttofly的博客 1893

【牛股启动线】副图指标使用技术说明,图文案例分享,通达信炒股指标

如上图,在紫色线在黑色虚线上时,在出现紫色柱线时,通常会出现强势拉升的行情​。柱线加长加上紫色线上扬,进场跟随做多抓强势行情,紫色柱线和紫色线同时做多持续则可以继续持股。如上图,副图指标【牛股启动线】,指标信号包括紫色线走势信号和紫色柱线信号,以及底部的四条虚线技术信号​,还有一条绿色的参考线,一条黑色的虚线两天分档线。如上图,参考买点,紫色柱线开始出现时进场买点,在上图标记的位置对应的就是进场买点​。紫色柱线加长+紫色线上扬,多头共振持股,行情继续拉升阶段,持股待涨或顺势​进场做多。

weixin_69760830的博客 1909

2.Vivado软件基础操作

在本章节,我们以一个简单的计数器实例,介绍FPGA开发软件Vivado的基础操作流程,计数器实例程序的设计,在本课程中先不同掌握,后续课程将针对verilog编程进行讲解。 打开Vivado软件,会看到如下的界面: 点击如下图所示的: 点击Next> 将这个地方,设置路径,注意路径必须是英文路径。且文件夹名称第一个字符不能为数字。所有路径的名称的字符数量不能超过144个符号。 点击Next> 点击Next> 点...

FPGA/MATLAB学习教程/源码/项目合作开发 4478

jvm内存使用测试

记一次摸不着头脑的FullGC问题 (Thumbnails压缩图片占用巨大内存)_thumbnails内存溢出-优快云博客 JVM实战:CMS和G1的物理内存归还机制_shrinkheapinsteps-优快云博客 JVM调优之探索CMS和G1的物理内存归还机制 - 简书

global_coding的博客 209

2023年全国青少年信息素养大赛复赛真题(C++智能算法复赛真题:带解析)

2023年全国青少年信息素养大赛复赛真题(C++智能算法复赛真题:带解析)

王老师青少年编程 2114

java 缩略图 内存溢出_Java修改图片尺寸,总是报内存溢出怎么解决?

项目需求:有很多尺寸很大的图片(图片大小可能几十MB,甚至上百MB),需要等比例缩小它们的尺寸,相当于生成缩略图。例如:原图8268x6201,需要压缩成400x300。我现在的方法:将图片整个读入内存,然后修改宽、高,最后写回磁盘。核心代码大概这样:BufferedImageoldImg=ImageIO.read(in);BufferedImagenewImg=newBuffere...

weixin_31616935的博客 1200

13、使用 Mathematica 撰写文本

本文详细介绍了如何使用 Mathematica 进行文本撰写与处理。内容涵盖文本输入、格式设置、结构化排版、超链接插入、翻译与拼写检查工具的使用,以及将笔记本导出为多种格式(如 PDF、HTML、LATEX 和 RTF)的方法。通过实例演示了创建专业文档的完整流程,包括样式设置、公式推导、标题编号、页眉页脚配置等操作。适合希望利用 Mathematica 编写学术论文、技术报告或教学资料的用户参考。

sony5的博客 208

OpenClaw安卓手机攻略

想在安卓手机上安装 OpenClaw,目前主要有两种主流方法:一种是使用专门的,操作简单直观;另一种是在命令行环境下进行,自由度更高。你可以根据自己的偏好和动手能力来选择。

suny8的专栏 2899

Thumbnails 压缩后反而变大

遇到的问题: 1.Thumbnails.scale效果会导致图片大小变大 scale值 原图片格式 2 1 0.8 0.6 0.4 0.2 jpeg 明显变大 变大 变大 变大 明显变小 变大 png 变大 变小 变小 变小 变小 最小 png经过压缩 ...

zhuy的博客 9928

二、Windows安装Docker到非C盘的全新教程(Windows版)

Windows安装Docker到非C盘的全新教程(Windows版)

funfan的博客 4万+

fullgc频繁的原因_记一次服务Full GC背后的内存泄漏问题,真是匪夷所思

1. 告警最近所负责的服务略频繁地收到4xx告警2. 问题定位1、查业务日志,没发现相关错误的日志2、查nginx access log,发现返回的状态码都是499,从request_uri查了一遍发现不是集中在某一个请求上,说明应该不是某个接口的问题了,有可能进程层面问题了。通过对upstream_addr 分类,可以看到问题基本都是集中在 某一台这台机器上3、网上资料了解到,499 是 ngi...

weixin_39517357的博客 1328

Python实战:打造学生信息管理系统

通过本教程,我们构建了一个简单的学生信息管理系统,实现了基本的添加、删除、修改和查询功能。当然,这个系统还有很多可以改进和扩展的地方,比如添加用户界面、增加数据持久化功能、支持批量操作等。简介:本文将介绍如何使用Python编写一个功能齐全的学生信息管理系统,包括添加、删除、修改和查询学生信息的基本操作。学生信息管理系统是学校日常管理中不可或缺的一部分,它能够帮助管理人员快速、准确地管理学生信息,提高工作效率。为了实现上述功能,我们可以设计一个包含学生信息的字典,并使用函数来封装各个操作。

铭渊老黄 1489

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

图片引起的内存溢出,如何解决的

如何解决内存溢出:(内存为什么会溢出呢) 内存缓存, 速度快, 而且不消耗流量, 最优先读取内存缓存 本地缓存, 速度较快, 也不消耗流量, 其次从本地读缓存 网络缓存, 速度慢, 消耗流量, 最后才从网络下载 一般是(80%)因为加载了很多图片,(20% 代码垃圾) 可以用三级缓存的方式来解决;先是内存缓存(速度快, 而且不消耗流量,最优先读取内存缓存), 再是本地缓存(速度较快, 也不消耗流...

wdx_1136346879的博客 3099

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

使用Thumbnails实现图片指定大小压缩

项目中有个要求,对上传服务器的图片大小进行判断,大于500k的图片要进行压缩处理,让其小于500k后在上传。 可以通过java api的ImageIO实现图片压缩,但是看了网上的博客普遍都说bug比较多,会有OOM内存溢出的现象。 Thumbnails插件是Google的插件,能指定不同的参数进行压缩操作。 比如:宽高(size),缩放(scale),制定质量比(outputQuality)等。 ...

DCFANS的博客 6502

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

java中用thumbnailator依赖写一个压缩图片的类,只要图片大小超过几兆就无限循环下去的详细代码实例?(经典)

java中用thumbnailator依赖写一个压缩图片的类,只要图片大小超过几兆就无限循环下去的详细代码实例?

gb4215287的博客 641

上传图片重新调整大小导致内存溢出oom

imageio.read 内存溢出

ray的博客 2644

利用Thumbnailator生成缩略图

对图片进行各种操作,等比例缩放,按照大小缩放,缩放,裁剪,转换格式,输出到各种流中。 首先你要引用thumbnailator 的jar包最新的版本现在是 0.4.8下载地址https://code.google.com/p/thumbnailator/ 包的使用api在 http://thumbnailator.googlecode.com/hg/javadoc/index.html里面,感觉

薛秋艳的博客 3067

net.coobird.thumbnailator.Thumbnails 库的使用

net.coobird.thumbnailator.Thumbnails的简单应用

CSH__的博客 3746

Java生成缩略图之Thumbnailator

Thumbnailator 是一个为Java界面更流畅的缩略图生成库。从API提供现有的图像文件和图像对象的缩略图中简化了缩略过程,两三行代码就能够从现有图片生成缩略图,且允许微调缩略图生成,同时保持了需要写入到最低限度的代码量。同时还支持根据一个目录批量生成缩略图。  http://code.google.com/p/thumbnailator/  版本:thumbnailator-

daolingren的博客 724

严重Full GC问题

综上所述,针对Full GC导致系统卡死的问题,需要综合考虑堆内存大小、内存泄漏、大对象处理、Finalizer的使用以及并发线程数等因素,通过优化配置和代码改进,来降低Full GC的频率和影响,提高系统的稳定性和性能。内存泄漏:Full GC通常是在老年代进行的,如果应用程序存在内存泄漏问题,老年代的对象会持续增加,导致Full GC的时间越来越长,最终引发系统卡死。优化大对象的处理:对于频繁创建的大对象,可以考虑使用对象池或者重用对象,以减少Full GC的负担。

kankan_s的专栏 1739

java thumbnails 内存_在Java Swt中缩放图像和内存消耗

我有一个Java SWT应用程序.在容器的调整大小方法中,我想调整图像的大小,使用以下代码显示.但是似乎-即使我处置所有(真的吗?)内存消耗一直在增加…我找不到我的错误.为什么这段代码会在哪里占用我的全部内存?这是Resize-Listener:tabCover.addListener(SWT.Resize, new Listener() {public void handleEvent(Even...

weixin_35285276的博客 380
上一篇: 2020最新面经总结
下一篇: java poi框架导出excel如何插入特殊字符(复选框勾选)
null.equals()
博客等级 码龄12年 209粉丝 46原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值