第1篇 JVM相关

JVM

堆、栈区、本地内存

JVM内存

线程共享区

JAVA堆 方法区,如果耗尽会抛出OOM异常Out of MemoryError

线程私有区

随线程死亡而消亡,在编译时确定所需内存大小

虚拟机栈、本地方法栈、程序计数器

多线程下抛出OOM,单线程抛出SstackOutflowError

直接内存:NIO会频繁使用该区域,直接内存大小不受java堆大小限制,但受本机总内存的限制。可通过MaxDirectMemorySize来设置,默认与堆内存最大值一样。所以也会抛出OOM异常

堆和栈的区别是什么?

1.栈的大小远小于堆内存

2.通过-Xss设置栈内存的大小。-Xms设置堆的开始时大小。 -Xmx设置堆的最大值

JDK 1.6 1.7 1.8的区别

1.6 运行时常量在方法区

1.7 运行时常量在堆,有方法区

1.8 没有方法区,运行时常量在堆,多了元空间,移入本地内存空间

为什么去除方法区

1.永久代存储类、常量、静态变量很容易遇到内存溢出问题,JDK8将类的元数据放入native memory,将字符串池和类的静态变量放入java堆,这样可以通过MaxMetaspaceSize来对元数据区大小进行调整,降低了出现永久代内存溢出的问题

2.对永久代调优的难度很大,JDK8采用此方法将元空间与堆的GC进行隔离。避免永久代引发的Full GC和OOM等问题。

JVM常用的内存参数


JAVA内存溢出

1.OOM:堆、栈、方法区、元数据区、直接内存中数据达到最大容量时产生

2.StackOverFlowError:如果线程请求的栈深度大于虚拟机锁运行的最大深度抛出该异常,其本质还是数据达到最大容量

堆溢出

产生原因

堆用于存储实例的对象,不断的创建对象,且保持应用,避免GC回收,就会到达产生OOM异常

java.lang.OutOfMemoryError:Java heap space

解决方法

使用-XX:+HeapDumpOnOutOfMemoryError可以让java虚拟机在出现内存溢出时产生当前堆内存快照以便进行异常分析,主要分析哪些对象占用了内存。亦可以用jmap将快照导出。检查哪些对象占用空间比较大,由此判断代码问题,没有问题的考虑调整堆参数

栈溢出

产生原因

线程请求的栈深度大于虚拟机锁允许的最大深度,抛出StackOverFlowError

虚拟机在扩展栈时无法申请到足够的内存空间,抛出OOM

解决办法

StackOverFlowError,通常是调用层级过多,死递归、死循环

OOM,多线程情况下,调小堆和栈容量来换取更多线程支持。另外增大物理内存;或者采用限流,负载均衡的方式,把压力降低。

方法区或元数据区溢出

产生原因

jdk1.6之前,运行时常量池还是方法区的一部分,当常量池满了之后抛出OOM

方法区和元数据区存放的是class相关的信息,如类名、访问修饰符、常量池、方法、静态变量;如果工程中的类比较多,而方法区或者元数据区太小,在启动的时候,容易抛出OOM

解决方案

1.7之前通过 -XX:PerSize,-XX:MaxPerSize,调整大小

1.8之后通过-XX:MetaspaceSize,-XX:MaxMetaspaceSize调整元数据区大小

直接内存溢出

产生原因

通常直接内存溢出的原因是NIO,直接内存溢出最大的特点是HeapDump文件看不出明显异常。

解决办法

直接内存大小不受java堆大小限制,但受本机总内存的限制,可以通过MaxDirectMemorySize来设置(默认值与堆内存最大值一样)

垃圾回收

主要是回收堆内存,基于分带的思想

堆内存:新生代(1/3堆空间)和老年代(2/3堆空间);新生代Eden:FROM:TO=8:1:1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,731评论 0 11
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,714评论 3 83
  • 在一个方法内部定义的变量都存储在栈中,当这个函数运行结束后,其对应的栈就会被回收,此时,在其方法体中定义的变量将不...
    Y了个J阅读 4,445评论 1 14
  • 内存溢出和内存泄漏的区别 内存溢出:out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,...
    Aimerwhy阅读 756评论 0 1
  • 介绍JVM中7个区域,然后把每个区域可能造成内存的溢出的情况说明 程序计数器:看做当前线程所执行的字节码行号指示器...
    jemmm阅读 2,247评论 0 9