记一次摸不着头脑的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

STM32 ST-LINK Utility固件烧录全流程详解与实战技巧

本文详细解析了使用STM32 ST-LINK Utility进行固件烧录的全流程与实战技巧。从硬件连接、软件安装、核心三步操作(连接、擦除、烧录)到进阶的选项字节配置与批量脚本烧录,提供了完整的避坑指南和问题排查方案,帮助开发者高效完成STM32程序下载。

lambda的博客 768

liquibase介绍

1、Liquibase还是Flyway Flyway和Liquibase都支持专业数据库重构和版本控制所需的所有功能,因此您将始终知道要处理的数据库模式的版本以及它是否与软件版本匹配。两种工具都集成在Maven或Gradle构建脚本中以及Spring Boot生态系统中,因此您可以完全自动化数据库重构。 Flyway使用SQL定义数据库更改,因此您可以定制SQL脚本,使其与基础数据库技术(例如Oracle或PostgreSQL)良好地配合使用。另一方面,使用Liquibase,您可以通过使用XML,YA

赶路人儿 7534

jvm内存使用测试

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

global_coding的博客 209

Abaqus 气动软体抓取器:从超弹性材料建模到抓取力仿真全流程解析

本文详细解析了Abaqus在气动软体抓取器仿真中的应用全流程,涵盖超弹性材料建模、接触设置优化到抓取力仿真等关键环节。通过实战案例分享Yeoh模型参数拟合、不可伸展层建模技巧及收敛优化策略,帮助工程师高效解决有限元仿真中的常见问题,提升软体机器人研发效率。

weixin_28689193的博客 238

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

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

weixin_31616935的博客 1200

激光甲烷传感器DIY指南:从DFB激光器选型到Herriott池光路搭建

本文详细介绍了如何DIY激光甲烷传感器,从DFB激光器选型到Herriott池光路搭建的全过程。通过TDLAS技术实现ppm级甲烷检测,适用于家用燃气泄漏监测和农业沼气监测等场景。文章包含核心器件选型、光路搭建技巧、信号调理方案及系统集成优化,为创客提供实用指南。

f9g0h的博客 594

分类模型AUC低于0.5?5个常见坑点排查指南(附代码示例)

本文针对分类模型AUC低于0.5的常见问题,提供了5个关键排查点及代码示例。从样本分布失衡、特征与标签脱节到量纲差异、模型初始化和数据泄露,详细解析了可能导致AUC异常的原因,并给出实用的诊断方法和解决方案,帮助开发者快速提升模型性能。

weixin_29190169的博客 239

Thumbnails 压缩后反而变大

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

zhuy的博客 9928

使用Simulink对固定翼无人机的自动起飞与降落进行仿真

本文介绍了基于Simulink的固定翼无人机自动起飞与降落控制系统设计方法。系统包含飞行器动力学模型、控制系统、环境模拟等模块,通过简化动力学方程描述无人机运动特性。详细说明了从创建模型、设置动力学方程、设计PID控制器(包括自动起飞和降落控制策略)到添加环境模拟的完整仿真流程。重点阐述了升降舵和发动机推力的控制律设计,以及性能评估要点。本方法可有效验证控制系统设计,优化飞行稳定性和安全性参数,为无人机自主控制提供仿真支持。

amy_mhd的博客 223

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

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

weixin_39517357的博客 1328

uniapp [安卓苹果App端] - 实现获取手机日历读写权限+调用本机日历数据及操作功能+日历中插入事项事件提醒,检测权限手机日历权限是否开启并引导用户同意授权,uniApp app端开启日历授权

uni-app,权限,手机日历权限,安卓Android,苹果ios,uniapp安卓android获取本机日历读写权限使用,uni-app获取日历权限并实现插入事项事件功能 uniapp苹果IOS系统不支持怎么办,判断权限,权限被拒绝了怎么办,获取日历权限报错,读取日历数据农历阴历并操作插入移除,给用户手机日历中放入一条提示,UniApp调用日历进行读写,打包上架后如何获取,安卓ios权限检测,安卓和ios权限获取,uniapp的APP端日历读写权限与使用示例代码,如何开启日历权限,日历的新增事项和删除,判

🏆 前端领域优质创作者 1万+

关于IBV_WR_RDMA_WRITE_WITH_IMM的理解

对于IBV_WC_RECV_RDMA_WITH_IMM的描述是这样的,也就是说并不需要sge,所以下发的sge,可以是NULL,个数可以是0。(1)需要下发post_recv,但是下发是post_recv当中的sge的地址可以是空,sge个数可以是0。伪代码,实际的rkey和addr已经通过socket交换。并且poll_cq时,有返回,在这篇文章当中对于poll_cq时,主要区别点有两个,这个是对于接收端而言。(2)可以带即时数据,

qq_38158479的博客 2418

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

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

wdx_1136346879的博客 3099

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

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

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

DCFANS的博客 6502

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

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、付费专栏及课程。

余额充值