交行2面 什么是内存溢出和内存走漏 如何处置

  • 电脑网络维修
  • 2024-11-15

内存溢出和内存走漏是咱们经常听到的两种内存治理疑问,那么,它们是如何造成的?又该如何处置?这篇文章,咱们来聊一聊。

一、内存溢出

内存溢出(OutOfMemoryError)是指程序在运转时尝试调配内存,但由于没有足够的内存可用,Java 虚构机(JVM)抛出了OutOfMemoryError失误。经常出现的内存溢出区域包含堆内存和终身代(在 Java 8 之后被元空间取代)。

1.造成的要素

造成内存溢出关键有以下几个要素:1. 堆内存溢出:创立少量对象,造成堆内存耗尽。2.栈内存溢出:递归调用过深,造成栈内存耗尽。3.终身代/元空间溢出:类加载过多,造成终身代/元空间耗尽。

上方咱们用三个示例,区分展现了堆内存溢出、栈内存溢出和终身代/元空间溢出的状况:

(1) 堆内存溢出

如下示例代码,经过始终向ArrayList参与对象来耗尽堆内存。

import java.util.ArrayList;import java.util.List;public class HeapMemoryOverflow {public static void main(String[] args) {List<Object> list = new ArrayList<>();while (true) {list.add(new Object());}}}

在运转上述HeapMemoryOverflow示例时,或者须要调整 JVM 参数以较小的堆大小运转,例如-Xmx10m,以更快地观察到OutOfMemoryError。

(2) 栈内存溢出

如下示例代码,经过递归调用一个没有中断条件的方法,造成栈内存溢出。

public class StackMemoryOverflow {public static void main(String[] args) {recursiveMethod();}public static void recursiveMethod() {// 没有中断条件的递归调用recursiveMethod();}}

运转StackOverflowError代码,通常会很快出现栈内存溢出,由于自动的栈大小不大。

(3) 终身代/元空间溢出

在 Java 8 之前,终身代溢出可以经过灵活生成少量类来模拟,Java 8 之后,终身代被元空间取代,以下是一个经常使用 CGLIB 灵活生成类的示例,或者造成元空间溢出,须要参与 CGLIB 库依赖。

import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class MetaspaceOverflow {public static void main(String[] args) {while (true) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(DummyClass.class);enhancer.setUseCache(false);enhancer.setCallback(new MethodInterceptor() {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {return proxy.invokeSuper(obj, args);}});enhancer.create();}}static class DummyClass {}}

运转MetaspaceOverflow示例时,可以经常使用 JVM 参数-XX:MaxMetaspaceSize=10m来限度元空间大小,以更快地观察到溢出。

2.处置方法

在这里,咱们只是给了一个大的思绪,关于内存溢出的排查上班也是一个很关键的常识点,咱们会在前面的文章中去具体引见。

二、内存走漏

内存走漏(Memory Leak)是指程序中存在一些对象,它们不再被经常使用,但由于依然被援用,渣滓回收器无法回收这些对象。因此,随着期间的推移,内存走漏会造成可用内存逐渐缩小,最终或者造成内存溢出。

1.造成的要素

造成内存走漏关键有以下几个要素:

上方咱们用三个示例,区分展现了内存走漏或者出现的场景:

(1) 静态汇合类造成的内存走漏

静态汇合类持有对象援用,造成这些对象无法被渣滓回收。

import java.util.ArrayList;import java.util.List;public class StaticCollectionLeak {// 静态汇合持有对象援用private static List<Object> objectList = new ArrayList<>();public static void main(String[] args) {for (int i = 0; i < 10000; i++) {// 每次创立一个新对象并参与到静态汇合中objectList.add(new Object());}// 即使在这里试图清算掉一些其余的援用System.gc();// 这些对象依然无法被回收,由于它们被静态汇合援用}}

(2) 监听器和回调未被移除

注册的监听器或回调未被移除,造成内存走漏。

import java.util.ArrayList;import java.util.List;public class ListenerLeak {private List<EventListener> listeners = new ArrayList<>();public void addListener(EventListener listener) {listeners.add(listener);}public void triggerEvent() {for (EventListener listener : listeners) {listener.onEvent();}}public static void main(String[] args) {ListenerLeak leakExample = new ListenerLeak();// 匿名类创立的监听器对象leakExample.addListener(new EventListener() {@Overridepublic void onEvent() {System.out.println("Event triggered");}});// 假定在某个时刻不再须要监听器,但未移除// listeners.remove(listener); // 应该移除不须要的监听器}}interface EventListener {void onEvent();}

(3) 长生命周期对象持有短生命周期对象

长生命周期对象不当持有短生命周期对象的援用,造成短生命周期对象无法被回收。

import java.util.HashMap;import java.util.Map;public class LongLifeCycleLeak {private static Map<String, byte[]> cache = new HashMap<>();public static void main(String[] args) {while (true) {// 短生命周期对象byte[]>

2.处置方法

在这里,咱们只是给了一个大的思绪,关于内存走漏的排查上班也是一个很关键的常识点,咱们会在前面的文章中去具体引见。

3.示例代码

上方示例代码,用于测试内存走漏。

import java.util.HashMap;import java.util.Map;public class MemoryLeakExample {private static Map<Integer, String> map = new HashMap<>();public static void main(String[] args) {for (int i = 0; i < 100000; i++) {map.put(i, "value" + i);}}}

在上方的代码中,假设map是一个常年存在的静态变量,并且没有及时清算,则或者造成内存走漏。

三、对比

关于内存溢出和内存走漏的比拟如下:

四、总结

本文,咱们剖析了Java的内存溢出和内存走漏并且应示例展现了它们造成的要素,应该说它们是比拟经常出现的内存治理疑问,假设在消费环境出现也是比拟头疼的疑问。所以在日常开发中,咱们必定要留意自己的代码格调和代码品质,尽量防止这些疑问的出现。

  • 关注微信

本网站的文章部分内容可能来源于网络和网友发布,仅供大家学习与参考,如有侵权,请联系站长进行删除处理,不代表本网站立场,转载联系作者并注明出处:https://duobeib.com/diannaowangluoweixiu/7274.html

猜你喜欢

热门标签

洗手盆如何疏浚梗塞 洗手盆为何梗塞 iPhone提价霸占4G市场等于原价8折 明码箱怎样设置明码锁 苏泊尔电饭锅保修多久 长城画龙G8253YN彩电输入指令画面变暗疑问检修 彩星彩电解除童锁方法大全 三星笔记本培修点上海 液晶显示器花屏培修视频 燃气热水器不热水要素 热水器不上班经常出现3种处置方法 无氟空调跟有氟空调有什么区别 norltz燃气热水器售后电话 大连站和大连北站哪个离周水子机场近 热水器显示屏亮显示温度不加热 铁猫牌保险箱高效开锁技巧 科技助力安保无忧 创维8R80 汽修 a1265和c3182是什么管 为什么电热水器不能即热 标致空调为什么不冷 神舟培修笔记本培修 dell1420内存更新 青岛自来水公司培修热线电话 包头美的洗衣机全国各市售后服务预定热线号码2024年修缮点降级 创维42k08rd更新 空调为什么运转异响 热水器为何会漏水 该如何处置 什么是可以自己处置的 重庆华帝售后电话 波轮洗衣机荡涤价格 鼎新热水器 留意了!不是水平疑问! 马桶产生了这5个现象 方便 极速 邢台空调移机电话上门服务 扬子空调缺点代码e4是什么疑问 宏基4736zG可以装置W11吗 奥克斯空调培修官方 为什么突然空调滴水很多 乐视s40air刷机包 未联络视的提高方向 官网培修 格力空调售后电话 皇明太阳能电话 看尚X55液晶电视进入工厂形式和软件更新方法 燃气热水器缺点代码

热门资讯

关注我们

微信公众号