没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
(原 本准备把内存模型单独放到某一篇文章的某个章节里面讲解,后来查阅了
国外很多文档才发现其实 JVM 内存模型的内容还蛮多的,所以直接作为一个章
节的基础知 识来讲解,可能该章节概念的东西比较多。一个开发 Java 的开发者,
一旦了解了 JVM 内存模型就能够更加深入地了解该语言的语言特性,可能这个
章节更多的 是概念,没有太多代码实例,所以希望读者谅解,有什么笔误来
Email 告知:silentbalanceyh@126.com, 本文尽量涵盖所有 Java 语言可以碰到
的和内存相关的内容,同样也会提到一些和内存相关的计算机语言的一些知识,
为草案。因为平时开发的时候没有特殊情况 不会进行内存管理,所以有可能有
笔误的地方比较多,我用的是 Windows 平台,所以本文涉及到的与操作系统相
关的只是仅仅局限于 Windows 平台。不 仅仅如此,这一个章节牵涉到的多线程
和另外一些内容并没有讲到,这里主要是结合 JVM 内部特性把本章节作为核心
的概念性章节来讲解,这样方便初学者深入以 及彻底理解 Java 语言)
本文章节:
1.JMM 简介
2.堆和栈
3.本机内存
4.防止内存泄漏
1.JMM 简介
i.内存模型概述
Java 平台自动集成了线程以及多处理器技术,这种集成程度比 Java 以前诞
生的计算机语言要厉害很多,该语言针对多种异构平台的平台独立性而使用的
多线程技术支持也是具有开拓性的一面,有时候在开发 Java 同步和线程安全要
求很严格的程序时,往往容易混淆的一个概念就是内存模型。究竟什么是内存
模型?内存模型描述了程序中各个变量(实例域、静态域和数组元素)之间的
关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量这样的
底层细节,对象最终是存储在内存里面的,这点没有错,但是编译器、运行库、
处理器或者系统缓存可以有特权在变量指定内存位置存储或者取出变量的值。
【JMM】(Java Memory Model 的缩写)允许编译器和缓存以数据在处理器特
定的缓存(或寄存器)和主存之间移动的次序拥有重要的特权,除非程序员使
用了 final 或 synchronized 明确请求了某些可见性的保证。
1)JSR133:
在 Java 语言规范里面指出了 JMM 是一个比较开拓性的尝试,这种尝试视
图定义一个一致的、跨平台的内存模型,但是它有一些比较细微而且很重要的
缺点。其实 Java 语言里面比较容易混淆的关键字主要是 synchronized 和
volatile,也因为这样在开发过程中往往开发者会忽略掉这些规则,这也使得编
写同步代码比较困难。
JSR133 本身的目的是为了修复原本 JMM 的一些缺陷而提出的,其本身的
制定目标有以下几个:
保留目前 JVM 的安全保证,以进行类型的安全检查:
提供(out-of-thin-air safety)无中生有安全性,这样“正确同步的”应该被
正式而且直观地定义
程序员要有信心开发多线程程序,当然没有其他办法使得并发程序变得
很容易开发,但是该规范的发布主要目标是为了减轻程序员理解内存模
型中的一些细节负担
提供大范围的流行硬件体系结构上的高性能 JVM 实现,现在的处理器在
它们的内存模型上有着很大的不同,JMM 应该能够适合于实际的尽可能
多的体系结构而不以性能为代价,这也是 Java 跨平台型设计的基础
提供一个同步的习惯用法,以允许发布一个对象使他不用同步就可见,
这种情况又称为初始化安全(initialization safety)的新的安全保证
对现有代码应该只有最小限度的影响
2)同步、异步【这里仅仅指概念上的理解,不牵涉到计算机底层基础的一
些操作】:
在系统开发过程,经常会遇到这几个基本概念,不论是网络通讯、对象之
间的消息通讯还是 Web 开发人员常用的 Http 请求都会遇到这样几个概念,经常
有人提到 Ajax 是异步通讯方式,那么究竟怎样的方式是这样的概念描述呢?
同步:同步就是在发出一个功能调用的时候,在没有得到响应之前,该调
用就不返回, 按照这样的定义,其实大部分程序的执行都是同步调用的,一般
情况下,在描述同步和异步操作的时候,主要是指代需要其他部件协作处理或
者需要协作响应的一些 任务处理。比如有一个线程 A,在 A 执行的过程中,可
能需要 B 提供一些相关的执行数据,当然触发 B 响应的就是 A 向 B 发送一个请
求或者说对 B 进行一个调用操 作,如果 A 在执行该操作的时候是同步的方式,
那么 A 就会停留在这个位置等待 B 给一个响应消息,在 B 没有任何响应消息回
来的时候,A 不能做其他事情,只能等 待,那么这样的情况,A 的操作就是一
个同步的简单说明。
异步:异步就是在发出一个功能调用的时候,不需要等待响应,继续进行
它该做的事情,一旦得到响应了过后给予一定的处理, 但是不影响正常的处理
过程的一种方式。比如有一个线程 A,在 A 执行的过程中,同样需要 B 提供一
些相关数据或者操作,当 A 向 B 发送一个请求或者对 B 进行调用 操作过后,A
不需要继续等待,而是执行 A 自己应该做的事情,一旦 B 有了响应过后会通知
A,A 接受到该异步请求的响应的时候会进行相关的处理,这种情况下 A 的操
作就是一个简单的异步操作。
3)可见性、可排序性
Java 内存模型的两个关键概念:可见性(Visibility)和可排序性
(Ordering)
开发过多线程程序的程序员都明白,synchronized 关键字强制实施一个线程
之间的互斥锁(相互排斥),该互斥锁防止每次有多个线程进入一个给定监控
器所保护的同步语句块,也就是说在该情况下,执行程序代码所独有的某些内
存是独占模式,其他的线程是不能针对它执行过程所独占的内存进行访问的,
这种情况称为该内存不可见。但是在该模型的同步模式中,还有另外一个方面:
JMM 中指出了,JVM 在处理该强制实施的时候可以提供一些内存的可见规则,
在该规则里面,它确保当存在一个同步块时,缓存被更新,当输入一个同步块
时,缓存失效。因此在 JVM 内部提供给定监控器保护的同步块之中,一个线程
所写入的值对于其余所有的执行由同一个监控器保护的同步块线程来说是可见
的,这就是一个简单的可见性的描述。这种机器保证编译器不会把指令从一个
同步块的内部移到外部,虽然有时候它会把指令由外部移动到内部。JMM 在缺
省情况下不做这样的保证——只要有多个线程访问相同变量时必须使用同步。
简单总结:
可见性就是在多核或者多线程运行过程中内存的一种共享模式,在 JMM 模
型里面,通过并发线程修改变量值的时候,必须将线程变量同步回主存过后,
其他线程才可能访问到。
【*:简单讲,内存的可见性使内存资源可以共享,当一个线程执行的时候
它所占有的内存,如果它占有的内存资源是可见的,那么这时候其他线程在一
定规则内是可以访问该内存资源的,这种规则是由 JMM 内部定义的,这种情况
下内存的该特性称为其可见性。】
可排序性提供了内存内部的访问顺序,在不同的程序针对不同的内存块进
行访问的时候,其访问不是无序的, 比如有一个内存块,A 和 B 需要访问的时
候,JMM 会提供一定的内存分配策略有序地分配它们使用的内存,而在内存的
调用过程也会变得有序地进行,内存的折中 性质可以简单理解为有序性。而在
Java 多线程程序里面,JMM 通过 Java 关键字 volatile 来保证内存的有序访问。
ii.JMM 结构:
1)简单分析:
Java 语言规范中提到过,JVM 中存在一个主存区(Main Memory 或 Java
Heap Memory),Java 中所有变量都是存在主存中的,对于所有线程进行共享,
而每个线程又存在自己的工作内存(Working Memory),工作内存中保存的
是主存中某些变量的拷贝,线程对所有变量的操作并非发生在主存区,而是发
生在工作内存中,而线程之间是不能直接相互访问,变量在程序中的传递,是
剩余63页未读,继续阅读
weixin_45870870
- 粉丝: 0
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0