深入理解jvm:Java内存管理机制

#java虚拟机内存区域
截图.png
##程序计数器(记录正在执行得虚拟机字节码指令得地址):
线程私有得一块很小得内存。用来记录代码执行得行号。用过程序计数器来选取下一条需要执行得字节码指令。峰值,循环,跳转,异常处理,线程恢复等基础功能都需要以来这个计数器来完成。
##java虚拟机栈
生命周期和线程相同。体现得是java方法得执行内存模型。
每个方法执行时都会创建一个栈帧用于存储“局部变量表”,”操作数栈“,”动态链接“,”方法出口“等信息。一个方法执行得过程就是栈帧在虚拟机栈中进栈和出栈的过程。
java内存常说的栈区其实就是虚拟机栈的一部分(局部变量表部分)。
##局部变量表:
存放编译期可知的各种基本数据类型,对象引用,returenAddress类型。
局部变量表的内存空间在编译期间完成了分配,当进入
一个方法时这个方法需要在帧中分配多大的局部变量内存空间是完全确定的。
java虚拟机栈中会出现两种异常:
StackOverflowError异常:线程清秀的栈升读大于虚拟机允许的深度。
OutOfMemoryError异常:虚拟机栈动态扩展的时候无法申请到足够的内存。
##本地方法栈
和虚拟机栈相识。虚拟机栈执行java方法。本地方法栈,执行Native方法服务。
##java堆
java堆是java虚拟机所管理的内存中最大的一块。所有线程共享,用于存放所有的数组和对象实例。
也是垃圾收集器管理的主要区域。如果堆内没有完成实例分配会抛出OutOfMemoryError异常。
堆又可以分为:

  • 新生代:
    GC经常光顾得区域
  • Eden 空间:
    对象创建后放在Eden空间中,当执行GC后,留存下来得对象被复制到To Survivor空间中去。
  • From Survivor空间:
    执行GC过后,当From中存放得对象年龄阈值已经达到了,直接复制到年老中去。否则复制到To中去。
  • To Survivor空间:
    当From空间被清空,则To和From调换位置,如果To区中被填满,则将所有对象放到年老代
  • 年老代:
    相对安全得区域,但是还是会被GC处理。

##方法区
用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。(以前使用永久代来实现方法区,Java8已经将方法区拆分成元空间,静态变量和常量池。其中元空间存放类得元信息在本地内存中,静态变量和常量池等并入堆中)
##运行时常量池
运行时常量池是方法区的一部分。用于存放编译期生成的各种字面量和符号的引用(也可以动态添加,比如String得intern()方法 )。

  • 字面量:相当于Java语言层面常量的概念
  • 引用:类和接口的全限定名,字段名称和描述符,方法名称和描述符

##直接内存
通过Native函数使用NIO直接使用的堆外内存(本机内存)

#内存溢出模拟:
##java堆内存溢出:
1、设置最大堆内存(-Xmx20m -Xms20m -Xmn20m -XX:+HeapDumpOnOutOfMemoryError)
clipboard.png
2、无限添加对象
clipboard1.png
3、执行代码查看内存发,可以发现堆内存急剧增加,并且报java.lang.OutOfMemoryError: Java heap space
clipboard2.png
##java 栈内存溢出
1、设置栈内存大小为1M (-Xss1m )
2、递归方式无限入栈
clipboard3.png
3、报栈内存溢出
clipboard4.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值