Java内存区域与内存溢出异常

简介:

Java内存区域与内存溢出异常

    先贴上一段参数设置

JAVA_OPTS=

    很多时候,将代码部署到服务器,都会对JAVA_OPTS进行一些操作,大多数情况对主要两个知道是干嘛的,其实的哪copy的算哪的。

    所以,看了点资料,想写点东西。

    Java虚拟机运行时数据区,主要包括以下部分:方法区、堆,它们是线程共用的部分;虚拟机栈、本地方法栈、程序计数器。下面我

大概讲讲如上几个部分。

1. 程序计数器。
    线程自己的数据区,用以记录当前线程所执行的字节码的行号指示器,主要用于在线程切换过程中,保证切换后能够恢复到正确的执行位置,此区域是惟一一个在Java虚拟机规范中没有规定任何OOM情况的区域。2. Java虚拟机栈。
    线程独自拥有,生命周期与线程相同。异常状况,若线程请求栈深度大于虚拟机所允许,则StackOverflowError,若虚拟机栈可动态扩展,在扩展无法申请得到足够内存则OOM。3. 本地方法栈。
    相对于虚拟机栈为虚拟机执行Java方法服务,本地方法栈则为虚拟机使到的Native方法服务。为线程私有空间。4. Java堆。
    线程共享区域,在虚拟机启动时创建,为GC管理的主要区域。可设置为固定或者可扩展大小,由-Xmx和-Xms控制,设置成一样即为固定。若无空间分配实例,且无法扩展,则OOM。5. 方法区。
    线程共享,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。此区域也要GC,主要是对常量池回收和对类型的卸载,会有OOM异常。(运行时常量池,用于存放编译期生成的各种字面量和符号引用,在类加载后存储,运行期间也可能将新的常量放入池中,如String类的intern()方法)。

 

  来几个简单实例。

  Java堆溢出:

package com.wdm.mem;import java.util.ArrayList;import java.util.List;/*
 * VM: -Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError */public class HeapOOM {    static class OOMObejct {
    }    public static void main(String[] args) {
        List<OOMObejct> list = new ArrayList<>();
        System.out.println("start");        int i = 0;        while (true) {
            i++;            if (i % 10000 == 0) {
                System.out.println(i);
            }
            list.add(new OOMObejct());
        }
    }
}

输出如下:

start10000200003000040000java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid21966.hprof ...
Heap dump file created [2399791 bytes in 0.014 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3210)
    at java.util.Arrays.copyOf(Arrays.java:3181)
    at java.util.ArrayList.grow(ArrayList.java:261)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
    at java.util.ArrayList.add(ArrayList.java:458)
    at com.wdm.mem.HeapOOM.main(HeapOOM.java:23)

 

  虚拟机栈和本地方法栈溢出:

   

   stackLen = 1 ++   main(String[] args) = "stack length:" +"main"11121212

 

运行时常量池溢出:

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=1M; support was removed in 8.0Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=1M; support was removed in 8.0package com.wdm.mem;import java.util.List;import java.util.ArrayList;/*
 * VM: -XX:PermSize=10M -XX:MaxPermSize=10M */public class RuntimeConsPoolOOM {    public static void main(String[] args) {
        List<String> list = new ArrayList<>();        int i = 0;        while (true) {
            list.add(String.valueOf(i++).intern());
        }
    }
}


JDK8已经不用这两个参数了:可以看这个http://www.cnblogs.com/paddix/p/5309550.html

 

PS:此文由看《深入理解Java虚拟机:JVM高级特性与最佳实践》而来

http://www.cnblogs.com/hawk-whu/p/6731260.html



本文转自 holy2009 51CTO博客,原文链接:http://blog.51cto.com/holy2010/1931842

相关文章
|
5天前
|
Java
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
|
5天前
|
Java
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
|
6天前
|
IDE 前端开发 Java
怎样避免 Java 中的 NoSuchFieldError 异常
在Java中避免NoSuchFieldError异常的关键在于确保类路径下没有不同版本的类文件冲突,避免反射时使用不存在的字段,以及确保所有依赖库版本兼容。编译和运行时使用的类版本应保持一致。
|
8天前
|
Java 编译器
如何避免在 Java 中出现 NoSuchElementException 异常
在Java中,`NoSuchElementException`通常发生在使用迭代器、枚举或流等遍历集合时,尝试访问不存在的元素。为了避免该异常,可以在访问前检查是否有下一个元素(如使用`hasNext()`方法),或者使用`Optional`类处理可能为空的情况。正确管理集合边界和条件判断是关键。
|
10天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
32 6
|
11天前
|
Java
Java异常捕捉处理和错误处理
Java异常捕捉处理和错误处理
12 1
|
12天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
29 2
|
14天前
|
存储 缓存 安全
Java内存模型(JMM):深入理解并发编程的基石####
【10月更文挑战第29天】 本文作为一篇技术性文章,旨在深入探讨Java内存模型(JMM)的核心概念、工作原理及其在并发编程中的应用。我们将从JMM的基本定义出发,逐步剖析其如何通过happens-before原则、volatile关键字、synchronized关键字等机制,解决多线程环境下的数据可见性、原子性和有序性问题。不同于常规摘要的简述方式,本摘要将直接概述文章的核心内容,为读者提供一个清晰的学习路径。 ####
35 2
|
4月前
|
算法 Java 开发者
Java面试题:Java内存探秘与多线程并发实战,Java内存模型及分区:理解Java堆、栈、方法区等内存区域的作用,垃圾收集机制:掌握常见的垃圾收集算法及其优缺点
Java面试题:Java内存探秘与多线程并发实战,Java内存模型及分区:理解Java堆、栈、方法区等内存区域的作用,垃圾收集机制:掌握常见的垃圾收集算法及其优缺点
39 0
|
算法 Java
【Java 虚拟机原理】垃圾回收算法 ( Java 虚拟机内存分区 | 垃圾回收机制 | 引用计数器算法 | 引用计数循环引用弊端 )
【Java 虚拟机原理】垃圾回收算法 ( Java 虚拟机内存分区 | 垃圾回收机制 | 引用计数器算法 | 引用计数循环引用弊端 )
143 0