内存溢出

深度理解JVM

China☆狼群 提交于 2019-11-28 03:02:04
深入理解 java 虚拟机 要讲的内容 了解历史 垃圾回收机制 性能监控工具 性能调优案例实战 认识类的文件结构 类加载机制 字节码执行引擎 虚拟机编译及运行时优化 Java 线程高级 1. 环境搭建 安装 jdk 2. 内存溢出场景模拟 public class Test01 { public static void main(String[] args) { //测试内存溢出 List<Demo> list = new ArrayList<Demo>(); while(true) { list.add(new Demo()); } //不停的创建对象会一直消耗堆内存知道内存消耗完(其实不会真的将8G的内存都消耗完) //当达到一个上线时就会报出这个错误了,这时就会报出一个内存溢出 //OutOfMemoryError } } class Demo{ } 可以在你的项目下找到这个快照的错误文件 但是我们是看不懂的所以需要到 http://www.eclipse.org/mat/downloads.php 去下载一个 eclipse 的 MemoryAnalyzer 分析工具 如果你直接下载会非常慢所以选择一个其他的镜像这样下载就会快点 下载解压后打开 点击 file->Open Heap Dump 选中产生的那个文件 然后生成一个 选中这个图标可以查看我们的堆内存运行情况

Java的内存溢出

对着背影说爱祢 提交于 2019-11-27 21:24:43
在Java中,内存溢出主要分为以下三种情况: 1. OutOfMemoryError : PermGen space Permanent Generation space 这个区域主要用来保存加来的Class的一些信息,在程序运行期间属于永久占用的,Java的GC不会对他进行释放,所以如果启动的程序加载的信息比较大,超出了这个空间的大小,就会发生溢出错误; 解决的办法无非就是增加空间分配了——增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大小,XX:MaxPermSize是最大永久保存区域大小。 2. OutOfMemoryError : Java heap space heap 是Java内存中的堆区,主要用来存放对象,当对象太多超出了空间大小,GC又来不及释放的时候,就会发生溢出错误。Java中对象的创建是可控的,但是对象的回收是由GC自动的,一般来说,当已存在对象没有引用(即不可达)的时候,GC就会定时的来回收对象,释放空间。但是因为程序的设计问题,导致对象可达但是又没有用(即前文提到的内存泄露),当这种情况越来越多的时候,问题就来了。 针对这个问题,我们需要做一下两点: (1) 检查程序,减少大量重复创建对象的死循环,减少内存泄露。 (2) 增加Java虚拟机中Xms(初始堆大小)和Xmx

JVM介绍(二):内存溢出

被刻印的时光 ゝ 提交于 2019-11-27 15:36:49
1、Java对象无法被垃圾收集器回收就会造成 内存泄漏 ,内存泄漏越来越多就可能会导致 内存溢出 (java.lang. OutOfMemoryError )。 2、内存溢出有以下几种情形: (1) 堆 溢出 (2) 虚拟机栈 (本地方法栈)溢出 (3) 方法区 (运行时常量池)溢出 (4) 直接内存 溢出 3、常用JVM参数: (1)- Xms 堆内存最小值;- Xmx 堆内存最大值(两个参数设置 值一样时则堆内存不可自动扩展 )。 (2)- Xss 虚拟机栈内存大小;- Xoss 本地方法栈内存大小(HotSpot中不区分虚拟机栈和本地方法栈,因此-Xoss参数对HotSpot虚拟机无效)。 (3)- XX:PermSize =方法区内存最小值,- XX:MaxPermSize =方法区内存最大值。 (4)- XX:MaxDirectMemorySize = 直接内存大小,如果不指定,则默认与Java堆最大值(-Xmx)一致。 来源: https://www.cnblogs.com/xy80hou/p/11368660.html

内存溢出和内存泄漏的区别

老子叫甜甜 提交于 2019-11-27 11:08:10
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。 内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。 memory leak会最终会导致out of memory! 内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。 内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出. 以发生的方式来分类,内存泄漏可以分为4类: 1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。 2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境

java内存溢出的定位和分析

巧了我就是萌 提交于 2019-11-27 02:35:05
内存溢出在实际的生产环境中经常会遇到,比如,不断的将数据写入到一个集合中,出现了死循环,读取超大的文件等,都会造成内存溢出。 如果出现了内存溢出,首先我们需要定位到发生内存溢出的环节,并进行分析,是正常情况还是非正常情况,如果是正常的需求,就应该考虑加大内存的设置,如果不是正常的需求,那么就要对代码进行修改,修复这个bug。 1.模拟内存溢出 public class TestJVMOutOfMemory { public static void main(String[] args) { List<Object> list = new ArrayList<>(); for (int i = 0; i < 1000000; i++) { StringBuilder str = new StringBuilder(); for (int j = 0; j < 1000; j++) { str.append(UUID.randomUUID().toString()); } list.add(str.toString()); } System.out.println("ok"); } } 设置启动参数以更快的出现问题 -Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError 测试结果如下: java.lang.OutOfMemoryError: Java

hotspot的Heap Memory和Native Memory

此生再无相见时 提交于 2019-11-26 23:43:07
JVM管理的内存可以总体划分为两部分:Heap Memory和Native Memory。前者供Java应用程序使用的;后者也称为C-Heap,是供JVM自身进程使用的。Native Memory没有相应的参数来控制大小,其大小依赖于操作系统进程的最大值,以及生成的Java字节码大小、创建的线程数量、维持java对象的状态信息大小(用于GC)以及一些第三方的包,比如JDBC驱动使用的native内存。 Native Memory里存些什么? (1)管理java heap的状态数据(用于GC); (2)JNI调用,也就是Native Stack; (3)JIT(即使编译器)编译时使用Native Memory,并且JIT的输入(Java字节码)和输出(可执行代码)也都是保存在Native Memory; (4)NIO direct buffer。对于IBM JVM和Hotspot,都可以通过-XX:MaxDirectMemorySize来设置nio直接缓冲区的最大值。默认是64M。超过这个时,会按照32M自动增大。 (5)对于IBM的JVM某些版本实现,类加载器和类信息都是保存在Native Memory中的。 DirectBuffer的好处 DirectBuffer访问更快,避免了从HeapBuffer还需要从java堆拷贝到本地堆,操作系统直接访问的是DirectBuffer

关于JVM内存溢出的原因分析及解决方案探讨

為{幸葍}努か 提交于 2019-11-26 23:35:43
前言:JVM中除了程序计数器,其他的区域都有可能会发生内存溢出。 0.什么是内存溢出 当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出。 1.内存泄漏和内存溢出区别与联系 内存泄漏:系统分配的内存没有被回收。 内存溢出:分配的内存空间超过系统内存。 2.内存泄漏的原因分析 jvm由5大块组成:堆,栈,本地方法栈,程序计数器,方法区。栈它的主要记录方法的执行和对象的引用。堆则存在真正的引用的对象。 内存泄漏是由于使用不当,把一部分内存“丢掉了”,导致这部分内存不可用。 当在堆中创建了对象,后来没有使用这个对象了,又没有把整个对象的相关引用设为null。此时垃圾收集器会认为这个对象是需要的,就不会清理这部分内存。这就会导致这部分内存不可用。 所以内存泄漏会导致可用的内存减少,进而会导致内存溢出。 3. JVM垃圾回收机制思想 就是从栈出发(root),遍历对象的引用,在遍历堆里面的引用对象,因为栈中的对象的引用执行完毕就删除,所以我们就可以通过栈中的对象的引用,查找到堆中没有被指向的对象,这些对象即为不可到达对象,对其进行垃圾回收。 4.内存溢出的原因分析 内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查: 是否App中的类中和引用变量过多使用了Static修饰

java--substring内存溢出问题

独自空忆成欢 提交于 2019-11-26 20:08:16
public class SubStringDemo { //substring() /** * jdk6 当调用 substring() 方法时,创建了一个新的String对象,但是string的value[] 属性域仍然指向堆内存中的原来的那个数组。区别就是 两个对象的 count 和 offset 这两个值不同了 * //JDK6,包级私有构造,共享 value数组提升速度 * String(int offset, int count, char value[]) { * this.value = value; * this.offset = offset; * this.count = count; * } * * * public String substring(int beginIndex, int endIndex) { * // ... 检查边界的代码 * // 如果范围和自己一模一样,则返回自身,否则用value字符数组构造一个新的对象 * return ((beginIndex == 0) && (endIndex == count)) ? this : * new String(offset + beginIndex, endIndex - beginIndex, value); * } * 如果有一个"非常"长的字符串,但每次使用substring(

Java内存泄漏与内存溢出

Deadly 提交于 2019-11-26 19:11:24
内存泄漏—内存溢出 一、内存泄漏: (1)概念:分配给对象的内存无法进行回收,造成资源浪费,终有一日会导致内存资源耗尽,内存溢出。 (2)场景:循环创建对象、连接没有关闭(数据库连接、网络连接、IO流等)、 (3)如何避免:及时关闭连接、尽量使用StringBuilder\StringBuffer 、减少静态变量(存放在方法区)等 二、内存溢出 (1)概念:OutOfMemory,程序申请的内存超过了系统分配的能力。 (2)场景:内存泄漏积累一定时间导致资源耗尽无法分配新内存、申请对象内存过大。加载类过多、递归调用太深等 (3)程序申请新内存: 来源: https://blog.csdn.net/qq_43251445/article/details/99048584

ThreadLocal内存泄露

旧巷老猫 提交于 2019-11-26 16:49:36
内存泄漏memory leak :是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。 内存溢出 out of memory :没内存可以分配给新的对象了。 我们知道,线程 Thread对象 中,每个线程对象 内部都有一个的ThreadLocalMap对象 。如果这个对象 存储了多个大对象 ,则可能造成 内存溢出OOM 。为了防止这种情况发生,在ThreadLocal的源码中,有对应的策略,即调用 get()、set()、remove() 方法时,均会清除 ThreadLocal内部的 内存。 ThreadLocal的内部是ThreadLocalMap 。ThreadLocalMap内部是由一个Entry数组组成 。Entry类的构造函数为 Entry(弱引用的ThreadLocal对象, Object value对象)。因为 Entry的key是一个弱引用的ThreadLocal对象 ,所以 在 垃圾回收 之前 ,将会 清除此Entry对象的key 。那么, ThreadLocalMap 中就会出现 key 为 null 的 Entry,就没有办法访问这些 key 为 null 的 Entry 的 value。这些 value 被Entry对象引用,所以value所占内存不会被释放。若在指定的线程任务里面