本地线程

Java内存区域与内存模型

主宰稳场 提交于 2019-12-01 15:27:58
Part 1 Java内存区域 在Java内存分配中,java将内存分为: 方法区 , 堆 , 虚拟机栈 , 本地方法栈 , 程序计数器 。其中方法区和堆对于所有线程共享,而虚拟机栈和本地方法栈还有程序计数器对于线程隔离的。每个区域都有各自的创建和销毁时间。 程序计数器: 作用是当前线程所执行的字节吗的行号指示器。Java的多线程是通过线程轮流切换并分配处理器执行时间方式来实现的。因此,每个线程为了能在切换后能恢复到正确的位置,每个线程需要独立的程序计数器。 Java 虚拟机栈: 每个放在被执行的时候都会同时创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。虚拟内存栈就是我们经常讲的“栈”。其中局部变量表所需内存是在编译期完成分配。 本地方法栈: 与虚拟机栈类似,区别在于虚拟机栈为虚拟机执行Java方法服务,而本地方法栈为虚拟机使用Native方法服务。 Java 堆: 被所有程序共享,并且在虚拟机启动时创建。此内存区域作用是存放对象实例。根据Java虚拟机规定,Java堆可以处于物理上不连续的内存空间,只要逻辑上连续即可。 方法区: 与堆相同,在各个线程间共享。作用是存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。 运行时常量池: 是方法区的一部分。作用是存储编译期生成的各种字面量和符号引用。 Part 2 Java内存模型

Java 内存分区

这一生的挚爱 提交于 2019-12-01 15:25:34
Java 内存分区主要分5个方面 1.程序计数器 又叫程序寄存器 线程私有 JVM支持多个线程同时运行,当每一个新线程被创建时,它都将得到它自己的PC寄存器(程序计数器)。如果线程正在执行的是一个Java方法(非native),那么PC寄存器的值将总是指向下一条将被执行的指令,如果方法是 native的,程序计数器寄存器的值不会被定义。 JVM的程序计数器寄存器的宽度足够保证可以持有一个返回地址或者native的指针。 2.Java栈 线程私有 JVM为每个新创建的线程都分配一个栈。也就是说,对于一个Java程序来说,它的运行就是通过对栈的操作来完成的。栈以帧为单位保存线程的状态。JVM对栈只进行两种操作:以帧为单位的压栈和出栈操作。我们知道,某个线程正在执行的方法称为此线程的当前方法。我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧,这个帧自然成为了当前帧。在此方法执行期间,这个帧将用来保存参数、局部变量、中间计算过程和其他数据。从Java的这种分配机制来看,堆栈又可以这样理解; 局部变量和对象引用都是放在栈区,代码运行完就会被自动回收。 3.Java堆 线程共享 成员变量 是属于对象所有的 所以是放在堆区 对象本身也是放在堆区 这是是JavaGC的核心 不会自动回收 jvm只有一个堆区(heap

Java内存分区

≯℡__Kan透↙ 提交于 2019-12-01 15:25:16
Java程序是交由JVM执行的,所以Java内存区域划分的时候事实上是指JVM区域划分 1、Java程序执行过程: 如图所示,首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。在整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作Runtime Data Area(运行时数据区)也就是我们常常说的JVM内存。因此,在Java中我们常常说到的内存管理就是针对这段空间进行管理(如何分配和回收内存空间)。 一、运行时数据区域包括五部分 根据《Java虚拟机规范》的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register)、Java栈(VM Stack)、本地方法区(Native Method Stack)、方法区(Method Area)、堆(Heap)。 如上图所示,JVM运行时数据区包括这五部分,在JVM规范中虽然规定了程序在执行期间运行时数据区应该包括这几部分,但是至于具体如何实现并没有做出规定,不同的虚拟机厂商可以有不同的实现方式。 二、运行时数据区的每部分到底存储了那些数据? 1、程序计数器 程序计数器(Program Counter Regist

Java多线程之线程安全(0)Java内存区域与Java内存模型

自作多情 提交于 2019-12-01 15:25:05
概况 本文内容 1.Java内存区域划分 2.Java内存模型JMM 3.硬件内存架构与Java内存模型 4.Jvm中线程实现机制 5.线程安全问题的原因 一.理解Java内存区域与Java内存模型 看下图 1.1Java内存区域 各个区域的解释和功能 方法区(Method Area): 方法区属于线程 共享 的内存区域,又称Non-Heap(非堆),主要用于 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码 等数据,根据Java 虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError 异常。值得注意的是在方法区中存在一个叫 运行时常量池(Runtime Constant Pool)的区域,它主要用于存放编译器生成的各种字面量和符号引用 ,这些内容将在类加载后存放到运行时常量池中,以便后续使用。 JVM堆(Java Heap): Java 堆也是属于线程 共享 的内存区域,它在虚拟机启动时创建,是Java 虚拟机所管理的内存中最大的一块,主要用于存放对象实例, 几乎所有的对象实例都在这里分配内存 ,注意Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做 GC 堆 ,如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError 异常。 程序计数器(Program Counter

Java内存区域

六月ゝ 毕业季﹏ 提交于 2019-12-01 15:24:51
JVM根据执行Java程序的过程中把它所管理的内存划分为若干个不同的数据区域。 1、程序计数器(Program Counter Register,PCR) 这是一块较小的内存空间,在JVM概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程回复等基础功能都需要依赖这个计数器来完成。 JVM的多线程是通过线程轮流切换并且分配处理器执行时间来实现的(并发,concurrent),因此为了线程切换之后能够恢复到正确的执行位置, 每条线程都需要一个独立的PCR,各条线程之间计数器互不影响,独立存储。 如果线程正在执行一个Java方法,则这个PCR记录的是正在执行的JVM字节码指令的地址;如果是native方法,这个计数器值为空(Undefined)。 这个内存区域是JVM规范中 唯一一个没有规定任何OutOfMemoryError的区域。 2、Java虚拟机栈(Java Virtual Machine Stacks) Java虚拟机栈也 是线程私有的 ,生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时会产生一个 栈帧(Stack Frame,方法运行时的基础数据结构) 用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用到执行完成

线程安全好文章

霸气de小男生 提交于 2019-12-01 13:26:36
转:https://www.cnblogs.com/lixinjie/p/10817860.html 不是线程的安全 面试官问:“什么是线程安全”,如果你不能很好的回答,那就请往下看吧。 论语中有句话叫“学而优则仕”,相信很多人都觉得是“学习好了可以做官”。然而,这样理解却是错的。切记望文生义。 同理,“线程安全”也不是指线程的安全,而是指内存的安全。为什么如此说呢?这和操作系统有关。 目前主流操作系统都是多任务的,即多个进程同时运行。为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的进程的,这是由操作系统保障的。 在每个进程的内存空间中都会有一块特殊的公共区域,通常称为堆(内存)。进程内的所有线程都可以访问到该区域,这就是造成问题的潜在原因。 假设某个线程把数据处理到一半,觉得很累,就去休息了一会,回来准备接着处理,却发现数据已经被修改了,不是自己离开时的样子了。可能被其它线程修改了。 比如把你住的小区看作一个进程,小区里的道路/绿化等就属于公共区域。你拿1万块钱往地上一扔,就回家睡觉去了。睡醒后你打算去把它捡回来,发现钱已经不见了。可能被别人拿走了。 因为公共区域人来人往,你放的东西在没有看管措施时,一定是不安全的。内存中的情况亦然如此。 所以线程安全指的是,在堆内存中的数据由于可以被任何线程访问到,在没有限制的情况下存在被意外修改的风险。

JAVA基础总结

非 Y 不嫁゛ 提交于 2019-12-01 13:16:56
Java基础 1.Java中的几种基本数据类型是什么,各自占用多少字节? 答案:int : 32bit;float :32bit; short :16bit; char :16bit; byte :8bit; double:64bit 2.springCloud微服务和插件问题? 3.JDK1.7和1.8的hashMap有啥不同? 答案:HashMap是Java程序员使用频率最高的用于映射(键值对)处理的数据类型。随着JDK(Java Developmet Kit)版本的更新,JDK1.8对HashMap底层的实现进行了优化,例如引入红黑树的数据结构和扩容的优化等。本文结合JDK1.7和JDK1.8的区别,深入探讨HashMap的结构实现和功能原理。 4.JAVA的各种几何的机制以及区别? 5.本地线程,多线程,以及线程池的问题? 答案:如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口更好了;新建状态(New)---->就绪状态(Runnable)(线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权)----->运行状态(Running)(就绪状态的线程获取了CPU,执行程序代码)-------->阻塞状态(Blocked)

ThreadLocal(线程本地存储)

房东的猫 提交于 2019-12-01 13:11:26
1. T hreadLocal ,即线程本地变量或线程本地存储。   threadlocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。 1.1 ThreadLocalMap(就是线程中的一个属性)   每个线程中都有一个自己的threadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。   将一个共用的threadlocal静态实例作为key,将不同对象的引用保存到不同线程的threadLocalMap中,然后在线程执行的各处通过这个静态threadlocal实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。   threadLocalMap其实就是线程里面的一个属性,他在thread类中定义。     ThreadLocal.ThreadLocalMap threadLocals=null; 使用场景:   最常见的threadlocal使用场景是用来解决数据库连接、session管理等。 1 private static final ThreadLocal threadSession = new ThreadLocal(); 2 public static Session getSession() throws

JVM知识点总结

两盒软妹~` 提交于 2019-12-01 12:13:24
原创: https://mp.weixin.qq.com/s?__biz=MzI4NDY5Mjc1Mg==&mid=2247484038&idx=1&sn=e083cc8b248461c8916a819119b059c3&chksm=ebf6daf9dc8153ef27ecd857e6cc85372735e84042679c133892d0993074371a46dd2c28b8b3&scene=21#wechat_redirect JVM体系总体分为四大块: 类的加载机制 JVM内存结构 GC算法 垃圾回收 GC分析 命令调优 类的加载机制 主要关注要点: 什么是类的加载 类的生命周期 类加载器 双亲委派模型 什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读取到内存中,将其放在运行时的数据区的方法区内,然后在堆区内创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品 是位于堆区内的Class对象,Class对象封装了类在方法区内的数据结构,并向Java程序员提供了访问方法区内数据结构的接口。 类的生命周期 类的生命周期包括这几个部分: 加载 连接 初始化 使用 卸载 其中前三部分是类的加载的过程,如下图: 加载,查找并加载类的二进制数据,在堆区内创建一个java.lang.Class类的对象 连接,连接又包含三部分内容

Java并发:线程安全与锁优化

时间秒杀一切 提交于 2019-12-01 11:07:08
概述 人们很难想象现实中的对象在一项工作进行期间,会被不停地中断和切换,对象的属性(数据)可能会在中断期间被修改和变“脏”,而这些事情在计算机世界中则是很正常的事情。有时候,良好的设计原则不得不向现实做出一些让步,我们必须让程序在计算机中正确无误地运行,然后再考虑如何将代码组织得更好,让程序运行更快。对于“高效并发”来说,首先需要保证并发的正确性,然后在此基础上实现高效。 1.线程安全 《Java Concurrency In Practice》的作者Brian Goetz对“线程安全”有一个比较恰当的定义:“当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的”。 这个定义比较严谨,它要求线程安全的代码都必须具备一个特征:代码本身封装了所有必要的正确性保障手段(如互斥同步等),令调用者无须关心多线程的问题,更无须自己采取任何措施来保证多线程的正确调用。这点听起来简单,但其实并不容易做到,在大多数场景中,我们都会将这个定义弱化一些,如果把“调用这个对象的行为”限定为“单次调用”,这个定义的其他描述也能够成立的话,我们就可以称它是线程安全了。 1.1 Java语言中的线程安全 按照线程安全的“安全程度”由强至弱来排序