阿里面试:Java开发中,应如何避免OOM
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的更多相关文章
- 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)
编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...
- Java开发中代码规范有哪些?
Java开发中所要遵守的编码规范大体上有如下7点.命名规范.注释规范.缩进排版规范.文件名规范.声明规范.语句规范以及编程规范. 1.命名规范 (1)所有的标示符都只能用ASCⅡ字母(A-Z或a-z) ...
- 轻松理解 Java开发中的依赖注入(DI)和控制反转(IOC)
前言 关于这个话题, 网上有很多文章,这里, 我希望通过最简单的话语与大家分享. 依赖注入和控制反转两个概念让很多初学这迷惑, 觉得玄之又玄,高深莫测. 这里想先说明两点: 依赖注入和控制反转不是高级 ...
- paip.java 开发中web server的选择jboss resin tomcat比较..
paip.java 开发中web server的选择jboss resin tomcat比较.. 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专 ...
- Java开发中常见的危险信号(中)
本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...
- Java开发中文件读取方式总结
JAVA开发中,免不了要读文件操作,读取文件,首先就需要获取文件的路径. 路径分为绝对路径和相对路径. 在文件系统中,绝对路径都是以盘符开始的,例如C:\abc\1.txt. 什么是相对路径呢?相对路 ...
- java开发中遇到的问题及解决方法(持续更新)
摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...
- Java开发中常见的危险信号(上)
本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...
- 完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络]
完整java开发中JDBC连接数据库代码和步骤[申明:来源于网络] 地址:http://blog.csdn.net/qq_35101189/article/details/53729720?ref=m ...
- Java 开发中的对象拷贝
前言 在 Java 开发中,很多时候需要将两个属性基本相同的对象进行属性复制,比如 DO 转 VO等等. 本文主要介绍自己实现的简易拷贝工具类与 Spring 提供的属性拷贝的对比. Spring 提 ...
随机推荐
- [转帖]Nginx 安全优化
目录 前言 1.使用 SSL/TLS 证书 2.使用安全密钥交换机制 3.禁用旧的 SSL/TLS 协议 4.禁用 SSL/TLS 弱密码套件 5.禁用不需要的 HTTP 方法 6.防止缓冲区溢出攻击 ...
- [转帖]nginx中的if和else语法
https://www.dyxmq.cn/it/nginx/nginx-if.html nginx支持if语法,语法和平常的代码格式差不多: 1 2 3 if ($xxx = xxx) { ...
- [转帖]linux将大目录等分切割成多个小目录
https://www.jianshu.com/p/6f9e6743a1dc 需求:有一个目录存放了数十万个文件,现在需要将这个目录上传,如果整个目录上传,中间因为某些故障断开连接了,可能又要从头开始 ...
- [转帖]TiUP Cluster 命令合集
https://docs.pingcap.com/zh/tidb/stable/tiup-component-cluster TiUP Cluster 是 TiUP 提供的使用 Golang 编写的集 ...
- [转帖]clickHouse单机模式安装部署(RPM安装)
关于版本和系统的选择 操作系统:Centos-7 ClickHouse: rpm 在安装,20.x 安装前的准备 CentOS7 打开文件数限 在 /etc/security/limits.conf ...
- shell的date的部分处理--需要记住..
在Linux中,可以使用date命令获取日期, date 获取当前完整日期 date --date="3 days ago" 获取3天前的完整日期 date --date=&quo ...
- IO调度算法的简单学习与整理
IO调度算法的简单学习与整理 前言 前几天整理了 /sys/block/sda/queue/nr_requests 以及 /sys/block/sda/device/queue_depth 的两个参数 ...
- linux 53端口占用的原因
解析 Linux 下 53 端口占用的现象 在 Linux 系统中,端口 53 往往是与域名解析服务(DNS)相关的.本文将详细介绍一个与端口 53 相关的情景,以及如何使用命令行工具来解析和理解这一 ...
- React类组件中事件绑定this指向的三种方式
有状态组件和无状态组件 函数组件又叫做无状态组件,类组件又叫做有状态组件. 状态又叫做数据 函数组件没有自己的状态,只负责静态页面的展示. 我们可以理解为纯ui展示.() 类组件有自己的状态,扶着更新 ...
- 【一个小发现】VictoriaMetrics 中 vmselect 的 `-search.denyPartialResponse` 选项不应该开启
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 一直以为vmselect 的 -search.denyPa ...