Java知识分享网 - 轻松学习从此开始!    

Java知识分享网

Java1234官方群25:java1234官方群17
Java1234官方群25:838462530
        
SpringBoot+SpringSecurity+Vue+ElementPlus权限系统实战课程 震撼发布        

最新Java全栈就业实战课程(免费)

springcloud分布式电商秒杀实战课程

IDEA永久激活

66套java实战课程无套路领取

锋哥开始收Java学员啦!

Python学习路线图

锋哥开始收Java学员啦!
当前位置: 主页 > Java文档 > Java基础相关 >

OutOfMemoryError_8种典型案例分享 PDF 下载


分享到:
时间:2021-06-11 09:13来源:http://www.java1234.com 作者:转载  侵权举报
OutOfMemoryError_8种典型案例分享 PDF 下载
失效链接处理
OutOfMemoryError_8种典型案例分享 PDF 下载


本站整理下载:
提取码:b656 
 
 
相关截图:
 
主要内容:

一个非常简单的示例 
以下代码非常简单, 程序试图分配容量为 2M 的 int 数组. 如果指定启动参数  ‐Xmx12m , 那么就会发生
java.lang.OutOfMemoryError: Java heap space  错误。而只要将参数稍微修改一下, 变成  ‐Xmx13m , 错误就不再
发生。
public class OOM {
    static final int SIZE=2*1024*1024;
    public static void main(String[] a) {
        int[] i = new int[SIZE];
    }
}
内存泄漏示例 
这个示例更真实一些。在Java中, 创建一个新对象时, 例如  Integer num = new Integer(5);  , 并不需要手动分配
内存。因为 JVM 自动封装并处理了内存分配. 在程序执行过程中, JVM 会在必要时检查内存中还有哪些对象仍在使
用, 而不再使用的那些对象则会被丢弃, 并将其占用的内存回收和重用。这个过程称为 垃圾收集. JVM中负责垃圾回
收的模块叫做 垃圾收集器(GC)。
Java的自动内存管理依赖 GC, GC会一遍又一遍地扫描内存区域, 将不使用的对象删除. 简单来说, Java中的内存泄
漏, 就是那些逻辑上不再使用的对象, 却没有被 垃圾收集程序 给干掉. 从而导致垃圾对象继续占用堆内存中, 逐
渐堆积, 最后产生 java.lang.OutOfMemoryError: Java heap space 错误。
很容易写个BUG程序, 来模拟内存泄漏:
import java.util.*;
public class KeylessEntry {
    static class Key {
        Integer id;
        Key(Integer id) {
        this.id = id;
        }
        @Override
        public int hashCode() {
        return id.hashCode();
        }
     }
    public static void main(String[] args) {
        Map m = new HashMap();
        while (true){
        for (int i = 0; i < 10000; i++){
           if (!m.containsKey(new Key(i))){
               m.put(new Key(i), "Number:" + i);
           }
        }
        System.out.println("m.size()=" + m.size());
        }
    }
}
粗略一看, 可能觉得没什么问题, 因为这最多缓存 10000 个元素嘛! 但仔细审查就会发现,  Key  这个类只重写了
hashCode()  方法, 却没有重写  equals()  方法, 于是就会一直往 HashMap 中添加更多的 Key。
请参考: Java中hashCode与equals方法的约定及重写原则
随着时间推移, “cached” 的对象会越来越多. 当泄漏的对象占满了所有的堆内存, GC 又清理不了, 就会抛出
java.lang.OutOfMemoryError:Java heap space 错误。
解决办法很简单, 在  Key  类中恰当地实现  equals()  方法即可:
@Override
public boolean equals(Object o) {
    boolean response = false;
    if (o instanceof Key) {
       response = (((Key)o).id).equals(this.id);
    }
    return response;
}
说实话, 在寻找真正的内存泄漏原因时, 你可能会死掉很多很多的脑细胞。
一个SpringMVC中的场景 
译者曾经碰到过这样一种场景:
为了轻易地兼容从 Struts2 迁移到 SpringMVC 的代码, 在 Controller 中直接获取 request.
所以在  ControllerBase  类中通过  ThreadLocal  缓存了当前线程所持有的 request 对象:
public abstract class ControllerBase {
    private static ThreadLocal<HttpServletRequest> requestThreadLocal = new
ThreadLocal<HttpServletRequest>();
    public static HttpServletRequest getRequest(){
        return requestThreadLocal.get();
    }
    public static void setRequest(HttpServletRequest request){
        if(null == request){
        requestThreadLocal.remove();
        return;
        }
        requestThreadLocal.set(request);
    }
}
然后在 SpringMVC的拦截器(Interceptor)实现类中, 在  preHandle  方法里, 将 request 对象保存到 ThreadLocal 中:

 

------分隔线----------------------------

锋哥公众号


锋哥微信


关注公众号
【Java资料站】
回复 666
获取 
66套java
从菜鸡到大神
项目实战课程

锋哥推荐