java内存模型和内存结构
java内存模型说的是多线程,网上可能会有写误导,并不是什么堆、栈、方法区,很多人都会搞混。说白了就是多线程中主线程和本地线程之间的一个数据可见性问题。
jmm:java内存模型;jvm:java内存结构
先看看多线程特性:
1、原子性:保证数据一致性和安全性
2、可见性:保证主线程中的共享变量进行修改后,本地线程能第一时间知道,这就是可见性,下面会配图和代码进行说明
3、有序性:jvm的一个重排序,提高线程的运行效率的
下面来看看java内存模型,代码很简单
package com.springboot; /**
* @Title: Java内存模型
* @Description:
* @author: sunxuesong@hztianque.com
* @date: Created in 9:18 2019/8/4
* @Modifired by:
*/
public class Thread001 extends Thread { private boolean flag = true; /**
* 子线程
*/
@Override
public void run() {
System.out.println("线程开始.."); while (flag) { }
System.out.println("线程结束..");
} public void setFlag(boolean flag) {
this.flag = flag;
} /**
* 主线程
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
Thread001 thread001 = new Thread001(); thread001.start();
Thread.sleep(3000);
thread001.setFlag(false);
System.out.println("flag已经改为false");
Thread.sleep(1000);
System.out.println("flag:" + thread001.flag);
}
}
结果:

可以看到线程进入了死循环,主线程明明已经修改了值为false但是子线程就是看不见,这就是可见性的问题。
怎么修改呢?其实很简单只需要在主线程中的flag变量前面加一个关键字,下面在看看结果:

加了关键字之后三秒后直接跳出死循环,这个关键字volatile可以保证当主线程中的值刷新了之后会立马通知到子线程。
但是volatile只能保证数据的可见性,不能保证原子性。延伸一点知识volatile和synchronize区别:
volatile比synchronize性能上要好很多,但是不能保证数据原子性。
synchronize性能上比volatile差很多,因为他在并发情况下只能有一个线程去执行,但是可以保证数据的原子性。
下面说一下Java的内存结构:jvm
jvm主要结构有方法区、堆、栈
方法区:加了static关键字的都是放在方法区中,它是存放在永久区中是不会被垃圾回收机制进行回收的,所以static关键字要慎用(又称为永久区),当class文件被加载就会被初始化
堆:通过关键字new出来的对象都是放在堆内存中,垃圾回收也是针对堆进行
栈和本地方法区:局部变量和类的方法,代码运行完毕自动释放内存,每个线程都是私有的,不会共享,也不会产生线程安全问题
下面用代码对方法区就行说明:很有趣的代码
public class Test001 {
private int count = 0;
/**
* 毫无疑问结果是2
* @param args
*/
public static void main(String[] args) {
Test001 test001 = new Test001();
++ test001.count;
++ test001.count;
System.out.println(test001.count);
}
}
再来看一个代码:
private static int count = 0;
/**
* 结果也是2
* 因为static修饰的变量它存放在方法区中,是被所有线程所共享的,或者说是jvm中全局的变量
* 不要定义太多的常量,有可能会出现内存溢出的情况,这也是jvm内存调优的一种方式,但是主要调优策略是在堆中,不是在方法区
* private static Test001 test003 = new Test001();这也是存放在方法区中,不要误解,凡是加了static都是存放在方法区中
* @param args
*/
public static void main(String[] args) {
Test001 test001 = new Test001();
Test001 test002 = new Test001();
++ test001.count;
++ test002.count;
System.out.println(test001.count);
}
jvm的内存结构就是这样子的了,切记内存模型和内存结构不要混淆,下节说一下jvm的垃圾回收机制
java内存模型和内存结构的更多相关文章
- java并发学习--第十章 java内存模型的内存语义
一.锁的内存语义 所为的java内存模型的内存语义指的就是在JVM中的实现原则. 锁的内存语义:锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息. 我们把上面这句话再整理下: ...
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序
并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...
- jvm内存模型-和内存分配以及jdk、jre、jvm是什么关系(阿里,美团,京东)
参考:JVM的垃圾回收机制 总结(垃圾收集.回收算法.垃圾回收器) 1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的.(2) ...
- Java内存模型与内存结构
Java内存模型 一.简介 Java内存模型(JMM)主要是为了规定线程和内存之间的一些关系:根据JMM的设计,系统存在一个主内存(Main Memory)和工作内存(Work Memory),Jav ...
- Java 内存模型与内存结构
Java内存模型 一.简介 Java内存模型(JMM)主要是为了规定线程和内存之间的一些关系:根据JMM的设计,系统存在一个主内存(Main Memory)和工作内存(Work Memory),Jav ...
- JAVA高级篇(二、JVM内存模型、内存管理之第一篇)
JVM内存结构如 Java堆(Heap),是Java虚拟机所管理的内存中最大的一块.Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建.此内存区域的唯一目的就是存放对象实例,几乎所有的对象实 ...
- 【深入Java虚拟机】之一:Java内存模型与内存溢出
[深入Java虚拟机]之:Java内存区域与内存溢出 高速缓存模型如下: ----------------------------------------------------分割线-------- ...
- java内存模型,内存区域
Java虚拟机内存区域总结:Java虚拟机相当于一个抽象的计算机操作系统, 其管理的内从区域大体上可以分为栈和堆,就像c或c++中对内存的分类一样, 但这样的分类对于Java虚拟机来说太过粗浅, 实际 ...
- jvm内存模型和内存分配
1.什么是jvm? (1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的. (2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和 ...
随机推荐
- VueI18n - 多语言国际化支持插件
VueI18n介绍 vue-i18n是一个vue组件,主要功能是提供国际化多语言的支持.例如项目中打印收费单功能,需要支持中英文打印,使用该组件就很容易的实现,而不必写两份打印单页面. 使用方法 安装 ...
- jquery each循环遍历完再执行的方法
jquery each循环遍历完再执行的方法 因为each是异步的 所以要加计数器. var eachcount=0; <pre> $(".emptytip").eac ...
- jquery swiper3自定义切换效果的方法
jquery swiper3自定义切换效果的方法 <pre> <div class="swiper-slide"> <div class=" ...
- 大宇java面试系列(一):jvm垃圾回收
1. 说一下 JVM 有哪些垃圾回收算法? 标记-清除算法:标记无用对象,然后进行清除回收.缺点:效率不高,无法清除垃圾碎片. 标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除 ...
- Unity - Cinemachine实现相机抖动
普通相机抖动脚本较易实现,但在使用cinemachine相机下,其Transform组件不可被代码改变,那么Cinemachine的相机抖动如何实现呢?本文结合实际项目,对实现相机抖动的三大步骤进行系 ...
- 微信web协议,群成员唯一uin,获取群成员唯一标识
群成员唯一标识获取接口 全网最新,支持调试测试.觉得OK再付款! 800元出售源码 不讲价 联系QQ:2052404477
- Python文件写入时的编码问题解决
如下代码: import sys import os import django root_dir = os.path.join(os.path.dirname(os.path.abspath(__f ...
- hdu 1024 Max Sum Plus Plus (动态规划)
Max Sum Plus PlusTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- nyoj 54-小明的存钱计划 (遍历 + 判断)
54-小明的存钱计划 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:5 submit:11 题目描述: 小明的零花钱一直都是自己管理.每个月的月初妈 ...
- Session,Token,Cookie相关区别
1. 为什么要有session的出现? 答:是由于网络中http协议造成的,因为http本身是无状态协议,这样,无法确定你的本次请求和上次请求是不是你发送的.如果要进行类似论坛登陆相关的操作,就实现不 ...