内存调优实战

news/2024/9/28 16:15:39

实战篇

1、内存调优

1.1 内存溢出和内存泄漏

内存泄漏(memory leak:在Java中如果不再使用一个对象,但是该对象依然在GC ROOT的引用链上,这个对象就不会被垃圾回收器回收,这种情况就称之为内存泄漏。

内存泄漏绝大多数情况都是由堆内存泄漏引起的,所以后续没有特别说明则讨论的都是堆内存泄漏。

 

比如图中,如果学生对象1不再使用

可以选择将ArrayList到学生对象1的引用删除:

或者将对象AArrayList的引用删除,这样所有的学生对象包括ArrayList都可以回收:

但是如果不移除这两个引用中的任何一个,学生对象1就属于内存泄漏了。

 

少量的内存泄漏可以容忍,但是如果发生持续的内存泄漏,就像滚雪球雪球越滚越大,不管有多大的内存迟早会被消耗完,最终导致的结果就是内存溢出但是产生内存溢出并不是只有内存泄漏这一种原因

这些学生对象如果都不再使用,越积越多,就会导致超过堆内存的上限出现内存溢出。

 

 

正常情况的内存结构图如下:

内存溢出出现时如下:

内存泄漏的对象和依然在GC ROOT引用链上需要使用的对象加起来占满了内存空间,无法为新的对象分配内存。

 

内存泄漏的常见场景:

1、内存泄漏导致溢出的常见场景是大型的Java后端应用中,在处理用户的请求之后,没有及时将用户的数据删除。随着用户请求数量越来越多,内存泄漏的对象占满了堆内存最终导致内存溢出。

这种产生的内存溢出会直接导致用户请求无法处理,影响用户的正常使用。重启可以恢复应用使用,但是在运行一段时间之后依然会出现内存溢出。

代码:

Java
package com.itheima.jvmoptimize.controller;

import com.itheima.jvmoptimize.entity.UserEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/leak2")
public class LeakController2 {
private static Map<Long,Object> userCache = new HashMap<>();

/**
* 登录接口 放入hashmap中
*/
@PostMapping("/login")
public void login(String name,Long id){
userCache.put(id,new byte[1024 * 1024 * 300]);
}


/**
* 登出接口,删除缓存的用户信息
*/

@GetMapping("/logout")
public void logout(Long id){
userCache.remove(id);
}

}

设置虚拟机参数,将最大堆内存设置为1g:

Postman中测试,登录id1的用户:

调用logout接口,id1那么数据会正常删除:

连续调用login传递不同的id,但是不调用logout

调用几次之后就会出现内存溢出:

 

2、第二种常见场景是分布式任务调度系统如Elastic-jobQuartz等进行任务调度时,被调度的Java应用在调度任务结束中出现了内存泄漏,最终导致多次调度之后内存溢出。

这种产生的内存溢出会导致应用执行下次的调度任务执行。同样重启可以恢复应用使用,但是在调度执行一段时间之后依然会出现内存溢出。

开启定时任务:

定时任务代码:

Java
package com.itheima.jvmoptimize.task;

import com.itheima.jvmoptimize.leakdemo.demo4.Outer;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class LeakTask {

private int count = 0;
private List<Object> list = new ArrayList<>();

@Scheduled(fixedRate = 100L)
public void test(){
System.out.println("定时任务调用" + ++count);
list.add(new Outer().newList());
}
}

启动程序之后很快就出现了内存溢出:

 

1.2 解决内存溢出的方法

首先要熟悉一些常用的监控工具:

1.2.1 常用监控工具

Top命令

top命令是linux下用来查看系统信息的一个命令,它提供给我们去实时地去查看系统的资源,比如执行时的进程、线程和系统参数等信息。进程使用的内存为RES(常驻内存)- SHR(共享内存)

优点:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

团队开发日记4

日期:2024年5月11日标题:校园兼职招聘系统开发日记 - 收藏功能和邮箱功能实现 项目概述:今天我们完成了用户收藏功能和邮箱功能的设计和实现,增强了系统的个性化和通知能力。 当天的工作内容:李健龙负责了用户收藏兼职和帖子的页面设计和数据存储逻辑。 郑盾实现了系统的邮…

团队开发日记2

日期:2024年5月5日标题:校园兼职招聘系统开发日记 - 兼职发布与搜索功能实现 项目概述:今天我们重点完成了兼职发布和搜索功能的初步实现,用户可以发布兼职信息并进行基本的搜索。 当天的工作内容:李健龙完成了兼职信息录入页面的前端设计和部分后端逻辑的编写。 郑盾实现…

[模式识别复习笔记] 第4章 SVM

1. SVM 简介 1.1 SVM 支持向量机 给定如图所示的线性可分训练集,能够将两类样本正确分开的直线很多。 感知机算法可以找到一条直线,且找到的直线不唯一。 然而感知机无法确定哪一条直线最优,但是 \(\text{SVM}\) 可以。 \(\text{SVM}\) 可以找到能够将训练样本正确分类的直线…

react 18 基础教程

1.React开发环境搭建执行 npx create-react-app 项目名称 命令来创建项目 2.实现列表渲染在react中可以通过在{}中写入js表达式来执行js代码,所以可以通过如下手段来执行来实现列表的渲染。 function App() {let list = [{id:1,name:"Vue"},{id:2,name:"React&…

成为MySQL DBA后,再看ORACLE数据库(十一、闪回技术)

前文说到ORACLE通过undo实现数据的多版本模型,同样的道理ORACLE还通过undo实现了闪回查询的特性,本文将总结ORACLE的几种闪回技术。闪回技术是Oracle数据库独有的特性,支持各级恢复,包括行、事务、表、表空间和数据库范围。采用闪回技术,可以针对行级和事务级发生过变化的…

KD散件组装的几种形式

介绍 KD指散件组装,英文全称为:knockdown。 KD有三种形式: CKD 、 SKD 、 DKD 。 CKD (Complete Knockdown)为全散件组装, SKD(Semi-Knockdown) 则是半散件组装,一部分总成是现成的。 DKD(Direct Knockdown) 直接组装或成品组装,如手机组装生产中,单机头整体进口,安装配…

面经梳理-计算机网络

梳理计算机网络相关面经前言 整理计算机网络的相关面试题,计算机网络在我看来挺复杂的,想要完全精通应该是不可能的,毕竟后端开发的知识点那么多,不过掌握面试的常考知识点是由必要的。建议系统学习计算机网络课本再进行知识点的整理记忆。 题目 OSI七层协议有了解么?Ip协…

手机gmail/qq邮箱添加西工大邮箱

为使gmail/qq邮箱可以收发西工大教育邮箱的邮件,我们需要进行以下设置:在电脑网页端登录西工大邮箱 https://mail.nwpu.edu.cn/ 登录后按如下步骤创建密码。和个人邮箱密码不同,该新建密码仅用于在gmail/qq邮箱上登录西工大邮箱账号时使用,且可生成多个。 在gmail中选择添加…