深入jvm自动内存管理机制

java内存溢出异常

java内存溢出异常

简述

  • 对于java而言,java在虚拟机(java virtual machine)的自动内存管理机制下,不需要为每一个new的对象进行free/delete方法,而且不容易出现内存泄漏和内存溢出的问题,看起来很美好。
  • 不过,正是因为java把内存交给了虚拟机,一旦出现了内存泄漏和内存溢出的问题,如果不了解虚拟机是怎么使用内存的,那么管理将是一个艰巨的工作。

运行时的数据区域

虚拟机在执行java过程的过程中,会将他所管理的内存划分为若干个不同的数据区域。这些区域各自有用途,以及创建和销毁时间,有的区域随着虚拟机进程启动而存在。


image.png
程序计数器
  • 程序计数器是指在一快较小的内存空间中,它的作用可以看作是当前线程所执行的字节码的行号指示器。字节码的解释器工作室通过改变这个解释器的指来选取下一跳需要执行的字节码命令,分支、循环、跳转、异常处理、线程恢复等功能都要依赖这个计数器完成。
java多线程的实现
  • java多线程是通过线程间轮流切换并且分配处理器的执行时间的方式来实现的,所以在任意一个确定的时刻,一个处理器只会执行一条线程中的命令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这条内存区域为线程私有区域。
  • 如果线程正在执行一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是Native方法,这个计数器的只为空。次内存区域是唯一一个在java虚拟机中没有规定outOFMemoryError情况的区域。
java虚拟栈
  • 和程序计数器一样,Java虚拟机栈 也是线程私有的,它的生命周期与线程相同。虚拟机描述的是java执行的内存模型。

程序理解

OutOfMemoryError
程序
Object object = new Object();
import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        ArrayList<BB> bbs = new ArrayList<>();
        while (true) bbs.add(new BB());
    }
}

class BB{
}

Object object 对应的Java栈的本地变量表中,作为一种reference类型数据出现
new Object() 对应的java栈的堆,形成了一块存储了Object类型所有实例数据值(Instance Data,对象中各个字段)的结构话内存。堆中还能查到此对象的类型数据(如对象类型,父类,实现接口,方法等)的地址信息,这些类型数据存储在方法区中。

[GC (Allocation Failure) [PSYoungGen: 8192K->1008K(9216K)] 8192K->5065K(19456K), 0.0077794 secs] [Times: user=0.04 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) --[PSYoungGen: 9200K->9200K(9216K)] 13257K->19432K(19456K), 0.0117182 secs] [Times: user=0.05 sys=0.01, real=0.01 secs] 
[Full GC (Ergonomics) [PSYoungGen: 9200K->0K(9216K)] [ParOldGen: 10232K->9747K(10240K)] 19432K->9747K(19456K), [Metaspace: 3076K->3076K(1056768K)], 0.1220499 secs] [Times: user=0.38 sys=0.00, real=0.12 secs] 
[Full GC (Ergonomics) [PSYoungGen: 7859K->8085K(9216K)] [ParOldGen: 9747K->7637K(10240K)] 17607K->15723K(19456K), [Metaspace: 3081K->3081K(1056768K)], 0.1289125 secs] [Times: user=0.48 sys=0.01, real=0.13 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 8085K->8067K(9216K)] [ParOldGen: 7637K->7637K(10240K)] 15723K->15705K(19456K), [Metaspace: 3081K->3081K(1056768K)], 0.0958057 secs] [Times: user=0.53 sys=0.00, real=0.10 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:265)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)
    at java.util.ArrayList.add(ArrayList.java:462)
    at Test.main(Test.java:6)
[Full GC (Ergonomics) [PSYoungGen: 8192K->0K(9216K)] [ParOldGen: 7637K->372K(10240K)] 15829K->372K(19456K), [Metaspace: 3106K->3106K(1056768K)], 0.0036833 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614938,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 372K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 3% used [0x00000007bec00000,0x00000007bec5d120,0x00000007bf600000)
 Metaspace       used 3113K, capacity 4500K, committed 4864K, reserved 1056768K
  class space    used 342K, capacity 388K, committed 512K, reserved 1048576K
StackOverflowError
public class JavaVmStackSOF {

    private int statckLeng = 1;
    public void add(){
        statckLeng ++;
        add();
    }

    public static void main(String[] args) {
        JavaVmStackSOF javaVmStackSOF = new JavaVmStackSOF();
        try {

            javaVmStackSOF.add();
        }
        catch (Exception e){
            System.out.println("stackLeng: "+ javaVmStackSOF.statckLeng);
            throw e;
        }
    }
}
Exception in thread "main" java.lang.StackOverflowError
    at JavaVmStackSOF.add(JavaVmStackSOF.java:6)
    at JavaVmStackSOF.add(JavaVmStackSOF.java:6)
    at JavaVmStackSOF.add(JavaVmStackSOF.java:6)

JVM参数

-Xoss参数

  • 设置本地方法栈大小虽然存在,但实际上是无效的

-Xss 参数

  • 栈容量只能由这个参数设定
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容