我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java中怎么避免OOM

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java中怎么避免OOM

Java中怎么避免OOM,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

一.了解 强引用、软引用、弱引用、虚引用的概念

在Java中,虽然不需要程序员手动去管理对象的生命周期,但是如果希望某些对象具备一定的生命周期的话(比如内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就需要用到软引用和弱引用了。

Java SE2开始,就提供了四种类型的引用:强引用、软引用、弱引用和虚引用。Java中提供这四种引用类型主要有两个目的:***是可以让程序员通过代码的方式决定某些对象的生命周期;第二是有利于JVM进行垃圾回收。下面来阐述一下这四种类型引用的概念:

1.强引用(StrongReference)

强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用:

Object object = new Object();  String str = "hello";

只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。比如下面这段代码:

public class Main {     public static void main(String[] args) {         new Main().fun1();     }     public void fun1() {         Object object = new Object();         Object[] objArr = new Object[1000];    }  }

如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。当运行至Object[] objArr = new Object[1000];这句时,如果内存不足,JVM会抛出OOM错误也不会回收object指向的对象。不过要注意的是,当fun1运行完之后,object和objArr都已经不存在了,所以它们指向的对象都会被JVM回收。

比如Vector类的clear方法中就是通过将引用赋值为null来实现清理工作的:

     public synchronized E remove(int index) {     modCount++;     if (index >= elementCount)         throw new ArrayIndexOutOfBoundsException(index);     Object oldValue = elementData[index];     int numMoved = elementCount - index - 1;     if (numMoved > 0)         System.arraycopy(elementData, index+1, elementData, index,                  numMoved);     elementData[--elementCount] = null; // Let gc do its work     return (E)oldValue;     }

2.软引用(SoftReference)

软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。下面是一个使用示例:

import java.lang.ref.SoftReference;  public class Main {     public static void main(String[] args) {          SoftReference<String> sr = new SoftReference<String>(new String("hello"));         System.out.println(sr.get());     }  }

3.弱引用(WeakReference)

弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。下面是使用示例:

import java.lang.ref.WeakReference;  public class Main {     public static void main(String[] args) {          WeakReference<String> sr = new WeakReference<String>(new String("hello"));          System.out.println(sr.get());         System.gc();                //通知JVM的gc进行垃圾回收         System.out.println(sr.get());     }  }

输出结果为:

hello  null

第二个输出结果是null,这说明只要JVM进行垃圾回收,被弱引用关联的对象必定会被回收掉。不过要注意的是,这里所说的被弱引用关联的对象是指只有弱引用与之关联,如果存在强引用同时与之关联,则进行垃圾回收时也不会回收该对象(软引用也是如此)。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。

4.虚引用(PhantomReference)

虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

二.进一步理解软引用和弱引用

import java.lang.ref.PhantomReference;  import java.lang.ref.ReferenceQueue;  public class Main {     public static void main(String[] args) {         ReferenceQueue<String> queue = new ReferenceQueue<String>();         PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);         System.out.println(pr.get());     }  }

对于强引用,我们平时在编写代码时经常会用到。而对于其他三种类型的引用,使用得最多的就是软引用和弱引用,这2种既有相似之处又有区别。它们都是用来描述非必需对象的,但是被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收。

在SoftReference类中,有三个方法,两个构造方法和一个get方法(WekReference类似):

两个构造方法:

public SoftReference(T referent) {     super(referent);     this.timestamp = clock;     } public SoftReference(T referent, ReferenceQueue<? super T> q) {     super(referent, q);     this.timestamp = clock;     }

在使用软引用和弱引用的时候,我们可以显示地通过System.gc()来通知JVM进行垃圾回收,但是要注意的是,虽然发出了通知,JVM不一定会立刻执行,也就是说这句是无法确保此时JVM一定会进行垃圾回收的。get方法用来获取与软引用关联的对象的引用,如果该对象被回收了,则返回null。

三.如何利用软引用和弱引用解决OOM问题

前面讲了关于软引用和弱引用相关的基础知识,那么到底如何利用它们来优化程序性能,从而避免OOM的问题呢?

下面举个例子,假如有一个应用需要读取大量的本地图片,如果每次读取图片都从硬盘读取,则会严重影响性能,但是如果全部加载到内存当中,又有可能造成内存溢出,此时使用软引用可以解决这个问题。

设计思路是:用一个HashMap来保存图片的路径 和 相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题。在Android开发中对于大量图片下载会经常用到。

.....  private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();  <br>....  public void addBitmapToCache(String path) {         // 强引用的Bitmap对象         Bitmap bitmap = BitmapFactory.decodeFile(path);         // 软引用的Bitmap对象         SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);         // 添加该对象到Map中使其缓存         imageCache.put(path, softBitmap);     }  public Bitmap getBitmapByPath(String path) {         // 从缓存中取软引用的Bitmap对象         SoftReference<Bitmap> softBitmap = imageCache.get(path);         // 判断是否存在软引用         if (softBitmap == null) {             return null;         }         // 取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得空         Bitmap bitmap = softBitmap.get();         return bitmap;     }

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网行业资讯频道,感谢您对编程网的支持。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java中怎么避免OOM

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java中怎么避免OOM

Java中怎么避免OOM,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一.了解 强引用、软引用、弱引用、虚引用的概念在Java中,虽然不需要程序员手动去管理对象
2023-06-17

【Java流式下载大文件,避免OOM内存溢出】

Java下载大文件,如何避免OOM内存溢出 Java下载文件时,如果是小文件的下载,我们一般直接使用工具类的方法,比如cn.hutool.http.HttpUtil.downloadFile()。但是如果是大文件的下载,使用这些工具类的方法
2023-08-25

MySQL中使用流式查询避免数据OOM

一、前言 程序访问MySQL数据库时,当查询出来的数据量特别大时,数据库驱动把加载到的数据全部加载到内存里,就有可能会导致内存溢出(OOM)。 其实在MySQL数据库中提供了流式查询,允许把符合条件的数据分批一部分一部分地加载到内存中,可以
2022-05-15

Java中怎么避免sql注入

小编给大家分享一下Java中怎么避免sql注入,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言sql注入是web开发中最常见的一种安全漏洞。可以用它来从数据库获
2023-06-26

怎么在Java中避免死锁

这篇文章给大家介绍怎么在Java中避免死锁,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程序员以优雅的思维
2023-06-14

Java中怎么避免反模式

本篇文章给大家分享的是有关Java中怎么避免反模式,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。使用接口,如:12345package one;public interface
2023-06-17

怎么避免java死锁

这篇文章主要介绍“怎么避免java死锁”,在日常操作中,相信很多人在怎么避免java死锁问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么避免java死锁”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!来到
2023-06-16

java中怎么避免程序死锁

本篇文章为大家展示了java中怎么避免程序死锁,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。  死锁发生的条件  互斥,共享资源只能被一个线程占用  占有且等待,线程 t1 已经取得共享资源 s1,
2023-06-02

Java项目中怎么避免循环依赖

本篇文章给大家分享的是有关Java项目中怎么避免循环依赖,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。举个例子:图中我们的API 库导入了一些库,但这些库同时依赖了库X的不同版
2023-06-15

如何解决Android中图片处理避免出现oom的问题

这篇文章主要介绍如何解决Android中图片处理避免出现oom的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. 通过设置采样率压缩res资源图片压缩 decodeResource public Bitmap
2023-05-30

java怎么避免空指针异常

在Java中,可以通过以下方法避免空指针异常:1. 对于可能为null的对象进行null检查。在使用可能为null的对象之前,先要进行null检查,可以使用if语句或三元运算符进行判断,确保对象不为null后再进行操作。例如:```java
2023-08-19

Java虚拟机OOM怎么用

本文小编为大家详细介绍“Java虚拟机OOM怎么用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java虚拟机OOM怎么用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。通过代码模拟Java虚拟机规范中描述的各个
2023-06-02

如何在Java中避免出现NullPointerException

今天就跟大家聊聊有关如何在Java中避免出现NullPointerException,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java中避免NullPointerExceptio
2023-05-31

Java怎么有效避免SQL注入漏洞

这篇文章主要介绍“Java怎么有效避免SQL注入漏洞”,在日常操作中,相信很多人在Java怎么有效避免SQL注入漏洞问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎么有效避免SQL注入漏洞”的疑惑有所
2023-06-22

java多线程怎么避免重复数据

在Java多线程编程中,避免重复数据的方法主要有以下几种:使用锁机制:在访问共享数据时,使用锁来保证同一时间只有一个线程能够访问该数据。可以使用synchronized关键字或者Lock接口来实现。使用线程安全的数据结构:Java提供了一些
java多线程怎么避免重复数据
2024-02-29

Python中怎么避免滥用try...except

这篇文章主要讲解了“Python中怎么避免滥用try...except”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python中怎么避免滥用try...except”吧!有不少人在写 Py
2023-06-16

怎么在python中避免KeyError异常

这篇文章将为大家详细讲解有关怎么在python中避免KeyError异常,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。python可以做什么Python是一种编程语言,内置了许多有效的工具,
2023-06-14

避免在Java中使用Checked Exception(转)

避免在Java中使用Checked Exception(转)[@more@]这篇文章指出了Java中checked Exception的一些缺点,提出应该在程序设计中避免使用checked Exception,对于需要处理checked E
2023-06-03

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录