Java内存管理:避免OOM的10个实用小技巧

引言

在Java开发中,OutOfMemoryError(OOM)错误一直是令开发者头疼的问题,也是Java面试中出现核心频率很高的问题。

那么我们究竟怎么样才能够有效正确的管理内存,日常开发中究竟要注意哪些核心技巧来避免OOM错误。

本文将带大家一起学习10个避免OOM的实用小技巧,让大家在工作中能够有的放矢,避免OOM错误的飞来横祸。

正文

1、 合理配置JVM内存参数

应用上线前,设置合理的JVM启动参数是避免OOM的第一步。

通过调整堆内存、栈内存和Metaspace的大小,可以有效地管理内存资源。

以4G内存为例,应用上线时可以参考如下配置:

// 示例:设置JVM的启动参数
// -Xms1024m 设置初始堆大小为1024MB
// -Xmx2048m 设置最大堆大小为2048MB
// -XX:NewSize=512m 设置新生代大小为512MB
// -XX:MaxNewSize=1024m 设置新生代最大大小为1024MB
// -XX:MetaspaceSize=256m 设置Metaspace的初始空间大小为256MB
// -XX:MaxMetaspaceSize=512m 设置Metaspace的最大空间大小为512MB

2、 使用轻量级对象

在开发过程中,尽可能的使用轻量级对象,减少内存消耗。

例如,使用原始数据类型代替包装类,使用StringBuffer/StringBuilder代替String进行字符串操作。

// 使用原始数据类型代替包装类
int i = 10; // 使用StringBuilder进行字符串拼接
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();`

3、 对象池技术

对于频繁创建和销毁的对象,可以考虑使用对象池技术,以减少GC的压力。

// 使用Commons Pool2实现对象池
// 定义一个简单的对象池工厂
public class MyObjectPoolFactory extends BasePooledObjectFactory<MyObject> {
@Override
public MyObject create() throws Exception {
return new MyObject();
} @Override
public PooledObject<MyObject> wrap(MyObject obj) {
return new DefaultPooledObject<>(obj);
}
} // 使用对象池
ObjectPool<MyObject> pool = new GenericObjectPool<>(new MyObjectPoolFactory());
MyObject obj = null;
try {
obj = pool.borrowObject();
// 使用对象...
} finally {
pool.returnObject(obj);
}``` **4、** **优化数据结构选择**
根据应用场景合理选择数据结构,例如,在频繁读取操作中使用ArrayList,在频繁插入删除操作中使用LinkedList。 ```java
// 在频繁读取操作中使用ArrayList
List<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Python");
String element = arrayList.get(0); // 在频繁插入删除操作中使用LinkedList
List<String> linkedList = new LinkedList<>();
linkedList.add("Java");
linkedList.add("Python");
linkedList.remove(0);

5、 避免创建不必要的对象

尽量复用已有对象,避免无谓的对象创建,特别是在循环或频繁调用的方法中。

// 避免在循环中创建对象
String result = "";
for(int i = 0; i < 100; i++) {
// 错误示范:在循环体内创建StringBuilder对象
// 正确做法是将StringBuilder的创建放到循环体外
StringBuilder sb = new StringBuilder(result);
sb.append(i);
result = sb.toString();
}

6、 及时释放不再使用的对象

确保不再使用的对象能够被GC及时回收,例如,将对象引用设置为null,关闭流等。

// 将对象引用设置为null
Object obj = new Object();
// 使用对象...
obj = null; // 明确标记obj不再使用 // 关闭流
FileInputStream fis = null;
try {
fis = new FileInputStream("test.txt");
// 使用流...
} finally {
if(fis != null) {
fis.close();
}
}

7、 使用软引用和弱引用管理内存

对于可回收的对象,使用软引用(SoftReference)或弱引用(WeakReference),以便在JVM内存不足时能被回收。

// 使用软引用
SoftReference<Object> softRef = new SoftReference<>(new Object());
// 使用弱引用
WeakReference<Object> weakRef = new WeakReference<>(new Object());

8、 合理使用缓存

合理设计缓存策略,避免缓存占用过多内存。可以使用第三方缓存库如Ehcache,Guava Cache等,并设置合理的过期策略。

// 使用Guava Cache
Cache<String, Object> cache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
// 向缓存中添加对象
cache.put("key", new Object());
// 从缓存中获取对象
Object obj = cache.getIfPresent("key");

9、 监控和分析内存使用

使用JVM提供的工具(如jvisualvm, jconsole)监控和分析应用的内存使用情况,及时发现并解决内存问题。

10、 优化GC策略

根据应用的实际情况,调整和优化GC策略,减少GC的执行时间,提升系统的性能。

本文总结

监控和分析内存使用

使用JVM提供的工具(如jvisualvm, jconsole)监控和分析应用的内存使用情况,及时发现并解决内存问题。

10、 优化GC策略

根据应用的实际情况,调整和优化GC策略,减少GC的执行时间,提升系统的性能。

本文总结

避免OOM错误并非难事,关键在于对Java内存管理有深入的理解和正确的实践。通过以上10个实用小技巧的应用,可以有效地管理和优化Java应用的内存使用,避免内存溢出的问题。务必记得,持续的监控、分析和优化是保持应用稳定运行的关键。

最后说一句(求关注,求赞,别白嫖我)

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。

这是大佬写的, 7701页的BAT大佬写的刷题笔记,让我offer拿到手软

本文,已收录于,我的技术网站 aijiangsir.com,有大厂完整面经,工作技术,架构师成长之路,等经验分享

求一键三连:点赞、分享、收藏

点赞对我真的非常重要!在线求赞,加个关注我会非常感激!

阿里面试:Java开发中,应如何避免OOM的更多相关文章

  1. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

  2. Java开发中代码规范有哪些?

    Java开发中所要遵守的编码规范大体上有如下7点.命名规范.注释规范.缩进排版规范.文件名规范.声明规范.语句规范以及编程规范. 1.命名规范 (1)所有的标示符都只能用ASCⅡ字母(A-Z或a-z) ...

  3. 轻松理解 Java开发中的依赖注入(DI)和控制反转(IOC)

    前言 关于这个话题, 网上有很多文章,这里, 我希望通过最简单的话语与大家分享. 依赖注入和控制反转两个概念让很多初学这迷惑, 觉得玄之又玄,高深莫测. 这里想先说明两点: 依赖注入和控制反转不是高级 ...

  4. paip.java 开发中web server的选择jboss resin tomcat比较..

    paip.java 开发中web server的选择jboss resin tomcat比较.. 作者Attilax  艾龙, EMAIL:1466519819@qq.com 来源:attilax的专 ...

  5. Java开发中常见的危险信号(中)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  6. Java开发中文件读取方式总结

    JAVA开发中,免不了要读文件操作,读取文件,首先就需要获取文件的路径. 路径分为绝对路径和相对路径. 在文件系统中,绝对路径都是以盘符开始的,例如C:\abc\1.txt. 什么是相对路径呢?相对路 ...

  7. java开发中遇到的问题及解决方法(持续更新)

    摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...

  8. Java开发中常见的危险信号(上)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  9. 完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络]

    完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络] 地址:http://blog.csdn.net/qq_35101189/article/details/53729720?ref=m ...

  10. Java 开发中的对象拷贝

    前言 在 Java 开发中,很多时候需要将两个属性基本相同的对象进行属性复制,比如 DO 转 VO等等. 本文主要介绍自己实现的简易拷贝工具类与 Spring 提供的属性拷贝的对比. Spring 提 ...

随机推荐

  1. Jrebel与Xrebel教学

    简介 JRebel和XRebel是两个非常有用的工具,可以显著提升Java开发人员的生产力和应用程序性能. JRebel是一个强大的Java开发工具,它允许开发人员在不重新启动应用程序的情况下进行代码 ...

  2. [转帖]clickhouse 超底层原理& 高可用集群 实操(史上最全)

    https://www.cnblogs.com/crazymakercircle/p/16718469.html 文章很长,而且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵 ...

  3. [转帖] 拒绝蛮力,高效查看Linux日志文件!

    https://www.cnblogs.com/codelogs/p/16410363.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 日常分析问题时 ...

  4. Springboot 使用nacos鉴权的简单步骤

    Springboot 使用nacos鉴权的简单步骤 背景 前端时间nacos爆出了漏洞. 因为他的默认token固定,容易被利用. 具体的问题为: QVD-2023-6271 漏洞描述:开源服务管理平 ...

  5. RabbitMQ 测试环境的简单创建于使用 permission vhost 以及 权限简单设置

    之前用docker运行起来 rabbitmq的容器了 但是今天发现有问题. 简单沟通了下 需要进行处理. 方法主要是如下 1. 运行容器: docker run --name rabbitmq -ti ...

  6. IPMI的简单使用

    背景 公司一台十一年前的服务器砸到我手中,要重装CentOS7的操作系统. 本着不想进机房, 不想格式化U盘的想法, 想用BMC进行安装系统. 遇到的第一个问题是不知道密码. 询问之前的机器持有人,也 ...

  7. git日志输出相关命令

    git log 默认输出所有的日志 git log 默认输出所有的日志 git 日志输出--只看最近的两条或者三条 有些时候我们可能只需要看最近的2或者3条日志 git log -2 日志输出--只看 ...

  8. vue结合elementUI折叠展开效果动画

    组件 <template> <div class="hide-page-com"> <ul class="tab-tilte"&g ...

  9. CLion搭建Qt开发环境,并解决目录重构问题(最新版)

    序言 Qt版本不断更新,QtCreator也不断更新.在Qt4和Qt5时代,我一直认为开发Qt最好的IDE就是自带的QtCreator,可是时至今日,到了Qt6时代,QtCreator已经都12.0. ...

  10. RestTemplate-postForObject详解、调用Https接口、源码解析,读懂这一篇文章就够了

    restTemplate 目录 restTemplate 1. 基本介绍 2. 常用方法分析及举例 2.1. get请求 2.2. post请求 3. springboot中使用restTemplat ...