Java内存总结

原创 2016年08月29日 15:06:59

一、java内存模型
1.内存模型图形

2.重排序
① 源代码
② 编译器重排序
③ 指令级重排序
④ 内存系统重排序
⑤ 最终执行指令序列
指令级重排序和内存系统重排序,属于处理级重排序。
可能会导致多线程出现内存可见性问题,编译器生成指令,会插入特定类型的内存屏障。
2、volatile内存语义的实现

是否能重排 第二个操作
第一个操作 普通读、写 volatile读 volatile写
普通读、写 YES YES NO
volatile读 NO NO NO
volatile写 YES NO NO
1、当第二个操作是volatile写时,不管第一个操作是什么,都不能重排序。这个规则确 保volatile写之前的操作不会被编译器重排序到volatile写之后。
2、当第一个操作是volatile读时,不管第二个操作是什么,都不能重排序。这个规则确 保volatile读之后的操作不会被编译器重排序到volatile读之前。
3、当第一个操作是volatile写,第二个操作是volatile读时,不能重排序。

1、volatile写之前插入StoreStore屏障;
2、volatile写之后插入StoreLoad屏障;
3、volatile读之后插入LoadLoad屏障;
4、volatile读之后插入LoadStore屏障;
3、锁

在ReentrantLock中,调用lock()方法获取锁;调用unlock()方法释放锁。
ReentrantLock的实现依赖于java同步器框架AbstractQueuedSynchronizer(本文简称之 为AQS)。AQS使用一个整型的volatile变量(命名为state)来维护同步状态,马上我 们会看到,这个volatile变量是ReentrantLock内存语义实现的关键。
4、Final
写final域的重排序规则
禁止把final域的写重排序到构造函数之外。这个规则的实现包含下面2个方面:
1、JMM禁止编译器把final域的写重排序到构造函数之外。
2、编译器会在final域的写之后,构造函数return之前,插入一个StoreStore屏障。这 个屏障禁止处理器把final域的写重排序到构造函数之外。

读final域的重排序规则如下:
1、在一个线程中,初次读对象引用与初次读该对象包含的final域,JMM禁止处理器重排序2、这两个操作(注意,这个规则仅仅针对处理器)。编译器会在读final域操作的前面插入一个LoadLoad屏障。
5、总结
1.jmm内存基本模型

2.Jmm重排序
三个Happen-before:程序顺序性规则、监视器锁规则、volatile规则、传递性。
重排序:编译器重排序、指令级重排序、内存系统重排序。
3.volatile
内存屏障:
volatile写前添加StoreStore屏障;
volatile写后添加StoreLoad屏障;
volatile读后添加LoadLoad屏障;
volatile读后添加LoadStore屏障;
4.final
final读前添加LoadLoad屏障;
final写后添加StoreStore屏障。
final字段不能逃逸构造函数,在访问final字段之前,访问对象之前必须应经被初 始化,初始化对象之前,final字段必须已经被赋值。
5.锁(synchronized、ReentrantLock、concurrent)
AQS中维护一个volatile变量,使用CAS操作内存语义。
二、JVM内存结构
包括:
1、java堆
存储对象,线程共享。OOM
Eden
Old
2、非堆(永久代)
本地方法栈
存储本地方法信息。共有区域。SOF
程序计数器
选择下一条需要执行的字节码指令,分支、跳转、循环等基础功能。私有区域。 OOM
方法区
类型信息(字段、方法)、常量池、静态变量、编译后的代码。共有区域。OOM
JVM栈
栈帧(局部变量表、常量引用、方法返回地址、附加信息、栈计数器),每个方法 调用都创建一个栈帧,该区域是私有的。单线程SOF,多线程OOM。

三、JVM垃圾回收机制
1.垃圾回收算法
标记-清除
标记-(清除)-压缩
复制
增量 分开逐个小区域回收
分代 几个区域不同寿命,一代代回收
并发 停顿
并行 多线程
2、垃圾回收器
年轻代:
Serial:(client模式)
新生代使用复制算法,暂停用户线程;
年老代使用标记整理算法,暂停用户线程;
ParNew:(server模式,多线程版本的Serial收集器)
新生代使用复制算法,暂停用户线程;(多线程)
年老代使用标记整理算法,暂停用户线程;
Parallel Scavenge:(吞吐量优先的收集器)

年老代:
CMS:(响应时间优先(最短回收停顿)的回收器)
使用标记-清除算法
四个阶段:
初始标记
并发标记
重复标记
并发清除

由于CMS会产生浮动垃圾,当回收过后,浮动垃圾如果产生过多,同时因为使用标记-清除算法会产生碎片,可能会导致回收过后的连续空间仍然不能容纳新生代移动过来或者新创建的大资源,因此会导致CMS回收失败,进而触发另外一次FULL GC,而这时候则采用SerialOld进行二次回收。
同时CMS因为可能产生浮动垃圾,而CMS在执行回收的同时新生代也有可能在进行回收操作,为了保证旧生代能够存放新生代转移过来的数据,CMS在旧生代内存到达全部容量的68%就触发了CMS的回收!

Serial Old:(Client)。
年老代使用标记整理算法,暂停用户线程;
Parallel Old:(老生代吞吐量优先的一个收集器)
使用标记整理算法

minorGC:担保GC就是担保minorGC能够满足当前的存储空间,而无需触发老生代的回收,由于大部分对象都是朝生夕死的,因此,在实际开发中这种很起效,但是也有可能会发生担保失败的情况,当担保失败的时候会触发FullGC,但是失败毕竟是少数,因此这种一般是很划算的。

版权声明:本文为博主原创文章,未经博主允许不得转载。

JavaWeb学习总结(四)——服务器

一、打包JavaWeb应用   在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命令的用法如下:    范例:将JavaWebDemoProject...
  • zw901159
  • zw901159
  • 2016年05月13日 19:30
  • 345

近期内存学习的几点心得

最近写代码对于内存分配这一方面遇到了一些现象,下面罗列下这些现象,小部分除了现象和推测还有解释。 1.malloc分配内存结构     char *p = (char *)malloc(1); ...
  • liu3daniel
  • liu3daniel
  • 2017年05月24日 10:22
  • 143

java 虚拟机内存总结

1、程序计数器是线程私有的,每一个线程都有属于自己的一个程序计数器,程序计数器的作用就是记录当前线程执行字节码的指令地址, 也正是因为每一个线程都有自己的程序计数器,所以在线程切换的时候才可以正确的...
  • liliangbing123
  • liliangbing123
  • 2013年07月09日 23:36
  • 644

JAVA内存关注总结

遇到过的坑分享 1.使用list时没有考虑到数据量大小,并发数上来后遍历此list越来越慢。 2,inter()的使用造成 (如fastjson) 引起的YGC时间越来越久 3, RPC调用用B...
  • lzf4712
  • lzf4712
  • 2017年02月11日 11:20
  • 182

JAVA内存总结

JAVA内存分配总结,如图
  • magic_wz
  • magic_wz
  • 2013年10月24日 15:45
  • 827

java内存简单总结

栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容 堆中存放使用new关键字创建的对象. public class Cat {     priva...
  • u012199710
  • u012199710
  • 2013年10月12日 09:50
  • 343

Java内存回收机制总结

此处将引用《深入理解Java虚拟机——JVM高级特性与最佳实践》这本书的一些内容。 1、对象已死?     垃圾回收是对堆中对象的管理,首先就要确定什么是垃圾,即什么情况下堆中的对象可以被回收...
  • gwpJava
  • gwpJava
  • 2015年04月07日 17:32
  • 417

我的Java开发技术总结

我的Java项目开发工具总结
  • cloud_ll
  • cloud_ll
  • 2016年06月04日 17:51
  • 1727

JAVA核心技术总结

技术总结 JAVA核心技术总结 J2EE技术总结 工作和学习总结 大数据相关技术总结...
  • huanggang028
  • huanggang028
  • 2015年05月06日 15:37
  • 1022

Java面试基础概念总结

前段时间由于忙于修改论文,就好久没更新博客,现在准备重新开始记录自己的屌丝人生。哈哈 面向对象软件开发的优点有哪些? 答:开发模块化,更易维护和修改;代码之间可以复用;增强代码的可靠性、灵活性和可理...
  • zjwcdd
  • zjwcdd
  • 2016年07月05日 13:02
  • 7797
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java内存总结
举报原因:
原因补充:

(最多只允许输入30个字)