JVM 自动内存管理机制

第二部分   自动内存管理机制java

1、java内存区域与内存溢出异常安全

 2.1运行时数据区并发

(五个组成!!!!!)函数

2.1.1  程序计数器:当前线程所执行的字节码的行号指示器,java方法:记录的是正在执行的虚拟机字节码指令的地址,若是正在执行得是Native方法这个计数器值为空。布局

2.1.2  虚拟机栈:生命周期与线程同样:建立,就绪,运行,死亡(中间可能出现赌塞)this

      描述java方法执行的内存模型,每一个方法在执行的同时,会建立一个栈贞,用于存储局部变量表,操做数栈,方法出口等。一个方法执行的过程就是栈针出栈入栈的过程。spa

 

虚拟机栈内容操作系统

局部变量表线程

1.基本数据类型指针

2.对象引用类型

3.returnAdress类型

 操做数栈

动态连接

方法出口

等等


本地方法栈:为本地方法服务


2.1.3  Java

   Java 堆是被全部线程共享的一块内存区域,在虚拟机启动时建立。这个区域是用来存放对象实例的,几乎全部对象实例都会在这里分配内存。堆是Java垃圾收集器管理的主要区域(GC堆),垃圾收集器实现了对象的自动销毁。Java堆能够细分为:新生代和老年代;再细致一点的有Eden空间,From Survivor空间,To Survivor空间等。Java堆能够处于物理上不连续的内存空间中,只要逻辑上是连续的便可,就像咱们的磁盘空间同样。能够经过-Xmx和-Xms控制

2.1.4方法区

是线程共享的内存区域,存储被虚拟机已经加载的类信息,常亮,静态变量,等等。

2.1.5 运行时常量池

  是方法区的一部分,用于存放编译期生成的各类字面量和符号引用,类加载以后将它们放进运行时常量池。

2.2.1 直接内存

   不是运行时数据区的一部分,在JDK1.4中,加入了NIO类,引入了一种基于通道与缓冲区的I/O方式,他可使用Native函数库直接分配堆外内存,经过存储在java堆中的DirectByteBuffer对象做为做为这块内存的引用进行操做,避免了Java堆和Native堆来回复制数据。

2.2.2  对象内存的建立

1、遇到new的指令,检查这个指令参数可否在常量池中定位到一个类的符号引用,检查这个引用表明的类是否已经被加载,解析,初始化过。若是没有,必须进行以上步骤。

2、虚拟机为新生对象分配内存:

   堆内存是规整的:指针碰撞(并发状况会引发线程安全问题)

  解决方案:1、同步处理

            2、每一个线程在java堆中预先分配一块内存称为本地线程分配缓冲。

   堆内存不是规整的:空闲列表

3.虚拟机将分配到的内存空间都初始化为0

4.接线来虚拟机对对象进行必要的设置

5.执行init()操做

2.2.3  对象的内存布局

   对象内存中存储布局能够分为3块区域:对象头,实例数据,对齐填充。

2.2.4 对象的访问定位

 句柄访问


2.2.5  Java堆溢出直接指针访问

Java堆用于不断的存储对象实例,到达必定的容量限制以后就会产生内存溢出异常。

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

   Java内存模型(重点!!!)


一、Java内存模型的三大特征

 1) 原子性:读取基本数据类型,不包括longdouble,read,load,assign,use,store,write操做。

  Synchronized块之间的操做也具备原子性。

2)可见性:volatile保证这点,与普通变量不一样的是,volatile保证新值可以当即同步到主内存,以及每次使用以前都先从主内存刷新。

     Synchronizedfinal,同步块是对一个变量执行unlock以前先把它同步回主内存,final是在构造器中一旦初始化完成,而且构造器没有把this的引用传递出去,那在其余线程中就能看到final字段的值

(3)有序性:volatilesynchornized  volatile自己就包含禁止指令重排序,synchornized容许在同一个时刻只容许一条线程对其进行lock操做。也就是持有同一个锁的两个同步块只能串行进入。

二、线程实现的三种方式

(1) 使用内核实现

(2) 使用用户线程实现

(3) 使用用户线程加轻量级进程混合实现。

(4) Java线程的实现:

Jdk1.2以前是基于“绿色线程”的用户线程来实现的。

Jdk1.2中是基于操做系统的原生模型来实现的

如今要不就是一对一模型要不就是同时支持一对一和多对多。

三、java线程调度

  系统为线程分配处理器使用权的过程,主要调度方式有:

  协同式线程调度:

  抢占式线程调度:

四、状态转换

线程阻塞和线程等待的区别:

阻塞状态:等待获取一个排他锁,这个事件将在另外一个线程放弃这个锁的时候发生。

等待状态:在等一段时间或者唤醒动做的发生,在程序等待进入同步区域的时候,线程处于此状态。