JVM学习总结(一)自动内存管理机制

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

一、运行时数据区域

java 虚拟机的内存模型分为两部分:一部分是线程共享的,包括 Java 堆和方法区;另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内存

 

 

1、程序计数器:

  • 当前线程所执行的字节码行号指示器,保证了程序的正常执行
  • 特点:1、线程私有 2、 是java虚拟机规范里面, 唯一 一个 没有规定任何 OutOfMemoryError 情况的区域 【原因是只保存指令偏移地址,不需要申请空间保存新的指令,因此不会有OutOfMemoryError异常】3、生命周期随着线程,线程启动而产生,线程结束而消亡。3如果执行的是native方法,计数器记录为空。

2、 java虚拟机栈

  • java虚拟机规范,对该区域规定了两种异常状况:
  • (1).线程请求的深度大于虚拟机所允许的深度跑出stackoverflowerror
  • (2).扩展到无法申请足够的内存跑出outofmemeryeeorr
  • java虚拟机栈是为虚拟机执行java方法服务

3、本地方法栈是native方法服务

4、JAVA堆

  • java堆是虚拟机管理的内存中最大的一块,被所有线程共享的区域 存放对象实例
  • 对象实例和数组都放在堆上 jit 即时编译
  • java堆是垃圾收集管理的主要区域(GC堆)
  • 分代收集算法分为新生代和老年代
  • 线程共享的java堆可能还可以分出不同的区,目的是更好地回收内存,更快的分配内存。大小通过-Xmx和-Xms控制
  • 如果堆中没有内存完成实例分配,并且堆也无法再扩展,抛出OutOfMemoryError 

5、 方法区

  • 永久代 内存上限(-XX:MaxPermSize)
  • 目前jdk1.7已经把原本放在永久代的字符串常量池移出。
  • 也会回收,针对常量池的回收和对类型的卸载
  • 如果方法区无法满足内存分配需求,抛出OutOfMemoryError 6

6、运行时的常量池

方法区的一部分,用于存放编译期产生的各种字面量和符号引用。具备动态性。

String类中的intern()方法 作用:就是重用String对象,以节省内存消耗。

  • 直接使用双引号声明出来的String对象会直接存储在常量池中。
  • 如果不是用双引号声明的String对象,可以使用String提供的intern方法。intern 方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中

 String s = new String("abc")创建了两个对象,第一个对象是”abc”字符串存储在常量池中,第二个对象在JAVA Heap中的 String 对象。

7、直接内存

jdk1.4后加入NIO,引入了基于通道和缓冲区的I/O方式,分配堆外内存 避免了java堆和native堆复制数据。受到本机总内存大小限制。如果配置各个内存大于物理内存限,也会报OutOfMemoryError

 

二、hotspot虚拟机对象

1、对象的创建

类加载通过后,为对象分配空间分为两种情况

垃圾收集器是否带有压缩整理功能:

有: java堆中内存规整,用过的放一边,空闲的内存的放一边,中间放指针做分界点的指示器。

分配方式:“指针碰撞” 指针向空闲内存空间挪一段与对象大小相等的位置 。

无:内存不规整,

分配方式:空闲列表 虚拟机需维护一个列表在表上做记录划分对象,更新记录。、、

 

并发线程安全考虑,1分配内存时虚拟机采用CAS配上失败重试的方式保证更新操作的原子性

2 本地线程分配缓冲 TLAB,分配动作按照线程划分,每个线程先分配一个内存块,用完的时候就锁定。通过参数-XX:+/-UseTLAB

2 、对象的内存布局

对象头,实例数据、对齐填充

对象头存储两部分数据

一部分自身的运行数据

 

第二部分存类型指针

实例数据,字段的内容,存储顺序受虚拟机分配策略参数和源码定义的顺序影响,默认相同宽度的字段分配到一起

填充:占位符,对象起始地址必须是8字节的整数倍

3 、对象的访问定位

访问方式两种:

句柄: java堆中会划分出一块内存作为句柄池,方法栈reference存储句柄地址

 

什么是逃逸分析(Escape Analysis)?

 

在编程语言的编译优化原理中,分析指针动态范围的方法称之为逃逸分析。它跟静态代码分析技术中的指针分析和外形分析类似。

通俗一点讲,当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了逃逸。

而用来分析这种逃逸现象的方法,就称之为逃逸分析。

 

3种常见的指针逃逸场景。分别是 全局变量赋值,方法返回值,实例引用传递。

逃逸分析另一个重要的优化 - 同步消除

JVM中启用逃逸分析 DoEscapeAnalysis

 

安装jdk1.6.0_14,运行java时传递jvm参数  -XX:+DoEscapeAnalysis

 

 

 

JVM中启用逃逸分析 DoEscapeAnalysis

 

安装jdk1.6.0_14,运行java时传递jvm参数  -XX:+DoEscapeAnalysis

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值