JVM——产生内存溢出原因

目录

  • 1.产生内存溢出原因一 :代码中的内存泄漏
    • 1.案例1:equals()和hashCode()导致的内存泄漏
      • 问题:
      • **正常情况**:
      • **异常情况:**
      • 解决方案:
    • 2.案例2:内部类引用外部类
      • 问题:
      • 解决方案:
    • 3.案例3:ThreadLocal的使用
      • 问题:
      • 解决方案:
    • 4.案例4:String的intern方法
      • 问题:
      • 解决方案:
    • 5案例5:通过静态字段保存对象
      • 问题:
      • 解决方案:
    • 案例6:资源没有正常关闭
      • 问题:
      • 解决方案:
  • 2.产生内存溢出原因二 : 并发请求问题
      • 模拟并发请求

1.产生内存溢出原因一 :代码中的内存泄漏

在这里插入图片描述

1.案例1:equals()和hashCode()导致的内存泄漏

问题:

⚫ 在定义新类时没有重写正确的equals()和hashCode()方法。在使用HashMap的场景下,如果使用这个类对象作为key,HashMap在判断key是否已经存在时会使用这些方法,如果重写方式不正确,会导致相同的数据被保存多份。


正常情况

1、以JDK8为例,首先调用hash方法计算key的哈希值,hash方法中会使用到key的hashcode方法。根据hash方法的结果决定存放的数组中位置。
2、如果没有元素,直接放入。如果有元素,先判断key是否相等,会用到equals方法,如果key相等,直接替换value;key不相等,走链表或者红黑树查找逻辑,其中也会使用equals比对是否相同。在这里插入图片描述

异常情况:

1、hashCode方法实现不正确,会导致相同id的学生对象计算出来的hash值不同,可能会被分到不同的槽中。在这里插入图片描述
2、equals方法实现不正确,会导致key在比对时,即便学生对象的id是相同的,也被认为是不同的key。在这里插入图片描述
3、长时间运行之后HashMap中会保存大量相同id的学生数据。在这里插入图片描述

解决方案:

1、在定义新实体时,始终重写equals()和hashCode()方法。
2、重写时一定要确定使用了唯一标识去区分不同的对象,比如用户的id等。
3、hashmap使用时尽量使用编号id等数据作为key,不要将整个实体类对象作为key存放

2.案例2:内部类引用外部类

问题:

⚫ 1、非静态的内部类默认会持有外部类,尽管代码上不再使用外部类,所以如果有地方引用了这个非静态内部类,会导致外部类也被引用,垃圾回收时无法回收这个外部类。
⚫ 2、匿名内部类对象如果在非静态方法中被创建,会持有调用者对象,垃圾回收时无法回收调用者

解决方案:

1、这个案例中,使用内部类的原因是可以直接获取到外部类中的成员变量值,简化开发。如果不想持有外部类
对象,应该使用静态内部类。
2、使用静态方法,可以避免匿名内部类持有调用者对象。

3.案例3:ThreadLocal的使用

问题:

如果仅仅使用手动创建的线程,就算没有调用ThreadLocal的remove方法清理数据,也不会产生内存泄漏。因为当线程被回收时,ThreadLocal也同样被回收。但是如果使用线程池就不一定了。

解决方案:

线程方法执行完,一定要调用ThreadLocal中的remove方法清理对象。

4.案例4:String的intern方法

问题:

JDK6中字符串常量池位于堆内存中的Perm Gen永久代中,如果不同字符串的intern方法被大量调用,字符串常量池会不停的变大超过永久代内存上限之后就会产生内存溢出问题。

解决方案:

1、注意代码中的逻辑,尽量不要将随机生成的字符串加入字符串常量池
2、增大永久代空间的大小,根据实际的测试/估算结果进行设置-XX:MaxPermSize=256M.

5案例5:通过静态字段保存对象

问题:

如果大量的数据在静态变量中被长期引用,数据就不会被释放,如果这些数据不再使用,就成为了内存泄漏。

解决方案:

1、尽量减少将对象长时间的保存在静态变量中,如果不再使用,必须将对象删除(比如在集合中)或者将静态变量设置为null。
2、使用单例模式时,尽量使用懒加载,而不是立即加载。
3、Spring的Bean中不要长期存放大对象,如果是缓存用于提升性能,尽量设置过期时间定期失效。

案例6:资源没有正常关闭

问题:

连接和流这些资源会占用内存,如果使用完之后没有关闭,这部分内存不一定会出现内存泄漏,但是会导致close方法不被执行。

解决方案:

1、为了防止出现这类的资源对象泄漏问题,必须在finally块中关闭不再使用的资源。
2、从 Java 7 开始,使用try-with-resources语法可以用于自动关闭资源。

2.产生内存溢出原因二 : 并发请求问题

⚫ 并发请求问题指的是用户通过发送请求向Java应用获取数据,正常情况下Java应用将数据返回之后,这部分数据就可以在内存中被释放掉。在这里插入图片描述
⚫ 并发请求问题指的是用户通过发送请求向Java应用获取数据,正常情况下Java应用将数据返回之后,这部分数据就可以在内存中被释放掉。但是由于用户的并发请求量有可能很大,同时处理数据的时间很长,导致大量的数据存在于内存中,最终超过了内存的上限,导致内存溢出。这类问题的处理思路和内存泄漏类似,首先要定位到对象产生的根源。
在这里插入图片描述

模拟并发请求

⚫ 使用Apache Jmeter软件可以进行并发请求测试。
⚫ Apache Jmeter是一款开源的测试软件,使用Java语言编写,最初是为了测试Web程序,目前已经发展成支
持数据库、消息队列、邮件协议等不同类型内容的测试工具。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/183763.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构-选择排序(简单选择、堆)

简单选择排序 基本思想 非常基础的算法,假设有N个数据,比较N-1轮,每轮选出当前剩余数据的最大(最小)放到数据 的开头,之后重复即可获得答案。 示例 代码 void SelectSort(OrderList *L) {RecordType t…

分享几种 Java8 中通过 Stream 对列表进行去重的方法

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 1. Stream 的 distinct…

Linux常用命令——badblocks命令

在线Linux命令查询工具 badblocks 查找磁盘中损坏的区块 补充说明 badblock命令用于查找磁盘中损坏的区块。 硬盘是一个损耗设备,当使用一段时间后可能会出现坏道等物理故障。电脑硬盘出现坏道后,如果不及时更换或进行技术处理,坏道就会越…

JavaScript图片处理大揭秘!掌握文件流处理方法

说在前面 💻作为一名前端开发,我们平时也少不了对文件流数据进行处理,今天简单整理一下日常开发中比较常见的一些处理文件流的场景及处理方法,希望可以帮助到大家,挤出多一点的摸鱼学习时间。 常见场景 一、input框上…

linux 磁盘扩容初始化挂载 笔记

目录 说明环境信息前提条件 操作步骤 说明 linux 系统磁盘扩容步骤 环境信息 系统信息:Linux version 4.19.90-23.8.v2101.ky10.aarch64cpu信息:Kunpeng-920 、aarch64、64-bit、HiSilicon 前提条件 有未初始化的用户磁盘操作系统可以支持当前磁盘的…

CentOS 8 安装国内、本地YUM源

环境:windows 11、 VMware 17、Cent OS 8 目的:加快软件下载速度 1、国内YUM源安装 使用国外的源,速度卡到不显示 备份默认YUM源文件 [rootlocalhost ~]# cd /etc/yum.repos.d/ [rootlocalhost yum.repos.d]# mkdir yum.bak [rootlocalho…

spring的事物

DataSourceTansactionManager Spring与JdbcTemplate或MyBatis框架集成时,提供的事务管理器. 事物的特性:原子性,一致性,隔离性,持久性 int TRANSACTION_READ_UNCOMMITTED 1; 未提交读 int TRANSACTION_READ_COMMITTED 2; …

一文秒懂|Linux字符设备驱动

我的圈子: 高级工程师聚集地 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强公司! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! …

Linux相关--笔试和面试高频

Linux RedHat公司已经宣布停止维护CentOS服务器操作系统,可以选择华为开源的欧拉系统、阿里开源的龙蜥系统和腾讯开源的TencentOS系统 面试 几个基本的Linux命令 pwd #查看当前绝对路径 结果/home/stu touch / vi编辑器 #创建文件 mkdir -p /home/stu/test #当…

记录仿钉钉审批流(将MySQL换成Oracle)走过的坑

需求:实现审批流程 在Gitee上发现了一个功能还OK的项目,于是就clone下来了(如下图) 原项目用MySQL很好启动,B站上作者还录制了视频,可以去学习 这里主要记录将MySQL换成Oracle出现的问题 首先&#xff0c…

【古月居《ros入门21讲》学习笔记】18_常用可视化工具的使用

目录 说明: 1. Qt工具箱 日志输出工具:rqt_console 绘制数据曲线:rqt_plot 图像渲染工具:rqt_image_view 综合工具:rqt 2. 三维可视化工具:Rviz Rviz启动 使用示例 3. 仿真平台:Gazebo…

【Openstack Train安装】四、MariaDB/RabbitMQ 安装

本章介绍了MariaDB/RabbitMQ的安装步骤,MariaDB/RabbitMQ仅需要在控制节点安装。 在安装MariaDB/RabbitMQ前,请确保您按照以下教程进行了相关配置: 【Openstack Train安装】一、虚拟机创建 【Openstack Train安装】二、NTP安装 【Opensta…

RK3568平台开发系列讲解(Linux系统篇)通过OF函数获取设备树节点实验

** 🚀返回专栏总目录 文章目录 一、获取获取设备树节点二、驱动程序沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍通过OF函数获取设备树节点实验 一、获取获取设备树节点 在 Linux 内核源码中提供了一系列的 of 操作函数来帮助我们获取到设备树中编写的…

Linux设置Nginx开机自启

文章目录 获取linux系统是多少位: getconf LONG_BIT获取CentOS版本: lsb_release -a获取nginx的版本: nginx -version第一步配置文件 vim /etc/rc.local最底部增加这一行: /usr/local/nginx/sbin/nginx 第二步注册systemctl服务 在/usr/lib/systemd/system目录…

计算机网络 一到二章 PPT 复习

啥币老师要隔段时间测试,我只能说坐胡狗吧旁边 第一章 这nm真的会考,我是绷不住的 这nm有五种,我一直以为只有三种 广播帧在后面的学习中经常遇到 虽然老师在上课的过程中并没有太过强调TCP/IP的连接和断开,但我必须强调一下&…

实施工程师运维工程师面试题

Linux 1.请使用命令行拉取SFTP服务器/data/20221108/123.csv 文件,到本机一/data/20221108目录中。 使用命令行拉取SFTP服务器文件到本机指定目录,可以使用sftp命令。假设SFTP服务器的IP地址为192.168.1.100,用户名为username,密…

5.如何利用ORBSLAM3生成可用于机器人/无人机导航的二维/三维栅格地图--以octomap为例

1 octomap的安装及官方文档 这里我们用ROS自带的安装方式即可: sudo apt install ros-melodic-octomap-msgs ros-melodic-octomap-ros ros-melodic- octomap-rviz-plugins ros-melodic-octomap-server 如上图就是安装成功了: 如果安装失败了,…

福德植保无人机:农业科技的未来已来

一、引言 随着科技的不断进步,无人机技术已经深入到各个领域。而在农业领域,福德植保无人机更是引领了科技潮流,为农业生产带来了革命性的改变。今天,让我们一起来了解福德植保无人机的魅力所在。 二、福德植保无人机的优势 高效作…

VSCODE 在新窗口中打开

使用VS习惯了,经常在新窗口中打开查看 但是VSCODE,无法拖动标签到一个新窗口中,一直以为没这个功能 后来发现 使用快捷健 ctlk,o 可以将标签页在新窗口中打开,虽然不如vsstudio方便,不过也可实现在新窗口打开的功能…