精华内容
下载资源
问答
  • 原标题:初级Java程序员必备知识点:线程私有区域线程私有数据区域生命周期与线程相同, 依赖用户线程启动/结束而创建/销毁(在Hotspot VM内, 每个线程都与操作系统本地线程直接映射, 因此这部分内存区域的存/否...

    原标题:初级Java程序员必备知识点:线程私有区域

    线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束而创建/销毁(在Hotspot VM内, 每个线程都与操作系统的本地线程直接映射, 因此这部分内存区域的存/否跟随本地线程的生/死)。

    b70fabbd07467a1affd67e3fff4d1349.png

    1.Native Method Stack本地方法栈

    是在Native Method Stack中登记native方法,在Execution Engine执行时加载native libraies。

    本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(譬如Sun HotSpot虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。

    2. PC Register程序计数器

    每个线程都有一个程序计算器,就是一个指针,指向方法区中的方法字节码(下一个将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。

    作用是当前线程所执行字节码的行号指示器(类似于传统CPU模型中的PC), PC在每次指令执行后自增, 维护下一个将要执行指令的地址. 在JVM模型中, 字节码解释器就是通过改变PC值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖PC完成(仅限于Java方法, Native方法该计数器值为undefined).

    不同于OS以进程为单位调度, JVM中的并发是通过线程切换并分配时间片执行来实现的. 在任何一个时刻, 一个处理器内核只会执行一条线程中的指令. 因此, 为了线程切换后能恢复到正确的执行位置, 每条线程都需要有一个独立的程序计数器, 这类内存被称为“线程私有”内存.

    3. Java Stack(虚拟机栈)

    栈也叫栈内存,主管Java程序的运行,是在线程创建时创建,它的生命期是跟随线程的生命期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题,只要线程一结束该栈就Over,生命周期和线程一致,是线程私有的。

    基本类型的变量和对象的引用变量都是在函数的栈内存中分配。

    栈帧中主要保存3类数据:

    本地变量(Local Variables):输入参数和输出参数以及方法内的变量;

    栈操作(Operand Stack):记录出栈、入栈的操作;

    栈帧数据(Frame Data):包括类文件、方法等等。

    栈运行原理

    栈中的数据都是以栈帧(Stack Frame)的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法和运行期数据的数据集,当一个方法A被调用时就产生了一个栈帧F1,并被压入到栈中,A方法又调用了B方法,于是产生栈帧F2也被压入栈,B方法又调用了C方法,于是产生栈帧F3也被压入栈…… 依次执行完毕后,先弹出后进......F3栈帧,再弹出F2栈帧,再弹出F1栈帧。

    遵循“先进后出”/“后进先出”原则。返回搜狐,查看更多

    责任编辑:

    展开全文
  • 根据使用情况,JVM运行时数据区域可分为六个区域:程序计数器虚拟机栈本地方法栈堆方法区运行时常量池如上所述,这些存储区域可以分为两类:线程私有(程序计数器,虚拟机栈,本机方法栈) 线程共享(堆,方法区,运行...

    Java虚拟机(JVM)定义了在程序执行期间使用的各种运行时数据区域,这些JVM数据区域中的某些区域是按线程创建的,其他区域则是在JVM启动时创建的,并且内存区域在线程之间共享。

    a28386fcf669cdea34995b17992c7883.png

    根据使用情况,JVM运行时数据区域可分为六个区域:

    程序计数器

    虚拟机栈

    本地方法栈

    方法区

    运行时常量池

    c27eeea2cb657ee915ff2658cc611b29.png

    如上所述,这些存储区域可以分为两类:

    线程私有(程序计数器,虚拟机栈,本机方法栈) 线程共享(堆,方法区,运行时常量池) 程序计数器

    在JVM中,在任何给定时间,可能正在执行许多线程。每个执行线程都有自己的PC寄存器。

    如果JVM线程执行的方法是JAVA方法,则PC寄存器包含当前正在执行的Java虚拟机指令的地址。如果线程正在执行本机方法,则Java虚拟机的pc寄存器的值未定义。

    虚拟机栈

    每个JVM线程都有自己的JVM堆栈,该堆栈在线程启动时创建。JVM堆栈存储被推入堆栈并从堆栈弹出的框架,而JVM堆栈永远不会被直接操纵。在发生任何异常时,您都可以通过此堆栈跟踪获取每个元素代表一个堆栈框架的位置。

    与Java虚拟机堆栈相关的特殊条件:

    如果线程中的计算需要比允许的Java虚拟机更大的堆栈,则Java虚拟机将抛出StackOverflowError。 如果可以动态扩展Java虚拟机堆栈,并且尝试进行扩展,但是可以提供足够的内存来实现扩展,或者如果没有足够的内存来为新线程创建初始Java虚拟机堆栈,则Java虚拟机机器抛出OutOfMemoryError。

    虚拟机栈中的框架

    调用方法时会创建一个新框架,然后将该框架推入该线程的JVM堆栈中。当框架的方法调用完成时,该框架将被销毁。

    每个框架都有自己的局部变量数组,自己的操作数堆栈以及对当前方法类的运行时常量池的引用。局部变量数组和操作数堆栈的大小在编译时确定,并与与帧关联的方法的代码一起提供。

    在任何时候,只有一个帧处于活动状态,这是执行方法的帧。该帧称为当前帧,其方法称为当前方法。定义当前方法的类是当前类。

    请注意,由线程创建的框架在该线程本地,并且不能被任何其他线程引用。

    局部变量 -创建并添加到JVM堆栈的每个框架都包含一个称为其局部变量的变量数组。局部变量数组的长度在编译时自行确定,并以类或接口的二进制表示形式以及与框架关联的方法的代码提供。 操作数堆栈 –每个帧都包含一个称为帧的操作数堆栈的后进先出(LIFO)堆栈。操作数堆栈的最大深度称为编译时间本身,并与与帧关联的方法的代码一起提供。 执行动态链接 -在已编译的.class文件中,方法的代码是指要调用的方法和要通过符号引用访问的变量。这些符号方法引用通过动态链接转换为具体的方法引用,并根据需要加载类以解析符号在那个时候还没有定义。   本地方法栈

    JVM也可以使用常规堆栈来支持本地方法,本地方法是用Java编程语言以外的其他语言编写的方法。创建每个线程时,将为每个线程分配本地方法栈。

    以下异常条件与本机方法堆栈相关联:

    如果线程中的计算所需的本机方法堆栈超出允许的范围,则Java虚拟机将引发StackOverflowError。 如果可以动态扩展本机方法堆栈并尝试进行本机方法堆栈扩展,但可以提供足够的内存,或者可以提供足够的内存来为新线程创建初始本机方法堆栈,则Java虚拟机将引发OutOfMemoryError。

    堆是JVM运行时数据区域,从中可以将内存分配给对象,实例变量和数组。堆是在JVM启动时创建的,并在所有Java虚拟机线程之间共享。一旦存储在堆中的对象没有任何引用,该对象的内存就会被垃圾收集器回收,该垃圾收集器是一种自动存储管理系统。对象永远不会显式释放。

    以下异常情况与堆相关联:

    如果计算需要的堆多于自动存储管理系统可以提供的堆,则Java虚拟机将引发OutOfMemoryError。

    方法区

    JVM具有在所有JVM线程之间共享的方法区域。方法区域存储有关已加载的类和接口的元数据。它存储每个类的结构,例如运行时常量池,字段和方法数据,以及方法和构造函数的代码。

    对于JVM加载的每种类型,存储在方法区域中的类型信息如下-

    类/接口的全限定名称。

    任何直接超类的完全限定名称。

    使用的修饰符。

    任何扩展超级接口的全限定名称。

    区分加载类型是类还是接口的信息。

    除类型信息方法区域外,还存储:

    运行时常量池。

    字段信息,包括字段名称,类型,修饰符。

    方法信息,包括方法名称,修饰符,返回类型,参数。

    静态(类)变量。

    方法代码,包含字节码,局部变量大小,操作数堆栈大小。

    方法区域通常是非堆存储器的一部分,以前被称为PermGen空间。注意, PermGen Space已从Java 8更改为MetaSpace。

    以下异常条件与方法区域相关联:

    如果无法使方法区域中的内存可用以满足分配请求,则Java虚拟机将抛出OutOfMemoryError。   运行时常量池

    运行时常量池是该类的constant_pool表的每个类或每个接口存储。Constant_pool包含在编译时已知的常量(字符串文字,数字文字),它还存储必须在运行时解析的方法和字段引用。

    运行时常量池在线程之间共享,并从JVM的方法区域分配。

    7e6ac99f06f6d76cf6f76841749072c1.png

    不是将所有内容存储在字节码中,而是为该类维护单独的常量池,并且字节码包含对常量池的引用。这些符号参考通过动态链接转换为具体的方法参考。

    展开全文
  • 是当前线程所执行字节码行号指示器,字节码解释器工作时通过改变计数器值来选取下一条需要执行字节码指令。 正在执行 java 方法话,计数器记录是虚拟机字节码指令地址(当前指令地址) 。如果还是 ...

    1.程序计数器

    是当前线程所执行的字节码的行号指示器,字节码解释器工作时通过改变计数器的值来选取下一条需要执行的字节码指令。
    正在执行 java 方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址) 。如果还是 Native 方法,则为空。

    2.虚拟机栈

    每个Java方法执行时都会创建一个栈帧到虚拟机栈中。
    一个栈帧包括局部变量表,操作栈,动态链接,方法出口等信息。
    写递归程序出错时时的栈溢出,就是发生在这里
    在这里插入图片描述

    3.本地方法栈

    与虚拟机栈相同,不过是服务于Native方法的。

    展开全文
  • Java线程并发:知识点发布:一个对象是使它能够被当前范围之外代码所引用:常见形式:将对象的的引用存储到公共静态域;非私有方法中返回引用;发布内部类实例,包含引用。逃逸:在对象尚未准备好时就将其发布。...

    Java线程并发:知识点

    发布:一个对象是使它能够被当前范围之外的代码所引用:

    常见形式:将对象的的引用存储到公共静态域;非私有方法中返回引用;发布内部类实例,包含引用。

    逃逸:在对象尚未准备好时就将其发布。

    不要让this引用在构造函数中逸出。例,在构造函数中启动线程,线程会包含对象的引用。

    同步容器:对容器的所有状态进行穿行访问,Vector、Hashtable,Cllections.synchronizedMap|List

    并发容器:ConcurrentHashMap,CopyOnWriteArrayList,ConcurrentLinkedQueue、BlockingQueue

    list 随机访问特性的优势。

    Blocking 增加了可阻塞的get set操作

    ConcurrentHashMap:分离锁,为并发访问带来的高的吞吐量,同时几乎没有损失单个线程的访问性能。返回弱一致性的迭代器。

    迭代器的弱一致性,在迭代器生成以后会检测容器的修改变化。

    并发容器 size(), isEmpty() 弱化,返回近似结果。

    CopyOnWriteArrayList:每次修改容器时复制,适用迭代需求大于修改需求情况。

    生产者消费者模式,运用有界阻塞队列解耦生产者和消费者的代码。

    Executor任务执行框架,实现了生产者消费者模式。

    SynchronousQueue:put等待消费者可用,take等待生产者可用,适用于消费者充足的情景。

    双端队列(deque)关联于窃取工作模式(work stealing),区别于生产者消费者模式中所有消费者共享一个工作队列,工作窃取模式每一个消费者都有自己的双端队列,如果一个消费者完成自己的全部工作,就可以偷取其它消费者队列队尾的任务。

    工作窃取模式适用于当运行到一个任务的某一个单元时,可能会识别出更多的任务,如遍历文件。

    当一个方法能够抛出InterruptedException时,说明它是可阻塞方法。抛出或捕获InterruptedException。

    Synchronizer:同步者---semaphore、barrier、latch,封装状态,决定线程在此状态下的行为(通过或阻塞),提供操控状态的方法,高效的等待同步者进入期望的状态。

    latch闭锁:延迟线程进度直到线程到达一个终点状态,像一个一次性开关。可以用来确保特定活动直到其它活动完成才发生。

    例如:

    确保一个计算不会被执行,直到需要的资源都被初始化。

    确保一个服务不会被开始,直到依赖的其它服务已经开始。

    等待,直到活动的所有部分都为继续处理做好准备。

    FutureTask可以作为闭锁,抽象的可携带结果的计算,通过callable实现。Future.get依赖于任务的执行状态,任务运行完成则返回结果,否则一直等待,

    Executor框架利用FutureTask完成异步任务。

    semapher信号量:用来控制能够同时访问某特定资源的活动数量或同时执行某一给定操作的数量,资源池,容器边界。

    barrier关卡:类似于闭锁,区别所有的线程必须同时到达关卡,才能继续处理,闭锁等待的是时间,关卡等待的是其它线程,重复使用。通过关卡,await会为每一个线程返回唯一的到达索引号,可以用它来选举产生一个领导,在下一次迭代中承担一些特殊任务。

    Exchanger一种关卡的形式。

    interrupt并不意味着必然停止目标线程正在进行的工作,它仅仅传递了请求中断的消息。

    中断通常是实现取消最好的选择。

    FutureTask和Executor框架可以构建可取消的任务和服务。

    Future.cancel

    『『

    try{

    future = ...

    }finally{

    future.cancel(); //不影响已完成的任务。

    }

    』』

    Executor.shutdown()  Executor.awaiTermination(Timeout, Unit) Executor.shutdownNow()

    生产者消费者模式,使用致命药丸停止含有线程的服务,让消费者确保所有的生产者都已停止

    Executor.shutdownNow试图取消正在进行的任务,并返回那些已经提交的,但并没有开始的任务清单,但是无法记录已经开始单未结束的任务。

    守护线程(deamon thread):主要用作执行一些辅助工作,同时又不阻碍JVM关闭。最典型的既是垃圾回收线程。区别于普通线程只是在退出时的区别。

    当一个线程退出时,JVM会检查一个运行中线程的详细清单,如果仅剩下守护线程,就会发生正常退出,JVM退出时,所有守护线程都会被抛弃,不会执行finally,也不会释放栈。

    可以周期性的执行一些清理工作。

    Timer:只有一个线程执行任务,可能发生较大的顺延;基于系统时间,可能会因为系统时间的修改而发生执行的变化。

    ScheduledExecutorService:作为timer的替代,一个任务一个线程;时间基于相对时间,可以基于rate,也可以基于FixedDelay。

    线程生命周期的管理

    任务执行框架的主要作用在于对任务的提交和任务的执行策略的解耦。

    ThreadLocal 保存线程自身本地变量版本。

    Catched 一分钟超时。

    saturation policy 饱和策略。RejectedExecutionHandler

    AbortPolicy:中断,execute抛出为检查的RejectedExecutionException,捕获异常处理。

    CallerRunsPolicy:主线程运行任务,阻断新任务的加入

    DiscardPolicy:丢弃,未能加入的任务丢弃

    DiscardOldestPolicy:策略选择丢弃本应该接下来就执行的任务,(注意:优先队列丢弃优先级最高的,不可组合使用)

    Lock对比与内部所Synchronized 更灵活,可中断(lockInterruptibly),可超时(tryLock(timeout)),公平锁(true),可轮询(tryLock)。必须在finally中释放锁。

    展开全文
  • 垃圾回收线程的意义在于实现虚拟机内存区域的自管理。 C++应用:堆内存使用周期完全由应用本身来决定,其遵循“谁申请、谁释放,谁创建、谁销毁”原则。 Java应用:堆内存使用周期由应用和虚拟机共...
  • 就是下面这个样子Java 运行时数据区域其中有些区域,随着 JDK 版本升级不断调整,例如:JDK 1.6,字符串常量池位于永久代运行时常量池中;JDK 1.7,字符串常量池从永久代剥离,放入了堆中;JDK 1.8,元空间...
  • 与程序计数器一样,Java虚拟机栈(Java Virtual Machine Stack)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧...
  • 就是下面这个样子:其中有些区域,随着 JDK 版本升级不断调整,例如:JDK 1.6,字符串常量池位于永久代运行时常量池中;JDK 1.7,字符串常量池从永久代剥离,放入了堆中;JDK 1.8,元空间取代了永久代,并且放...
  • 器,这类内存也称为“线程私有内存。 正在执行 java 方法话,计数器记录是虚拟机字节码指令地址(当前指令地址) 。如果还是 Native 方法,则为空。 这个内存区域是唯一一个在虚拟机中没有规定任何 ...
  • 文章目录1、JVM简介2、Java内存区域与内存溢出异常 1、JVM简介 1.1JVM简介 (1)虚拟机简介: JVM(Java Virtual Machine简介,意为Java虚拟机) 虚拟机:指通过软件模拟具有完整硬件功能,运行在一个...
  • 文章目录JVM 内存模型线程私有区域程序计数器虚拟机栈栈帧组成StackOverflowError本地方法栈逃逸分析优化线程私有部分回收问题参考 JVM 内存模型 .java 源文件 -> javac 工具编译 -> .class 文件 -> ...
  • 「属于线程私有的内存区域」 栈帧(Stack Frame) 栈帧(Stack Frame)是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack) 的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一...
  • 定义: JVM全称Java Virtual Machine(Java程序运行环境(Java二进制字节码运行环境)) 好处: 1.一次编译,到处运行(跨平台) 2.自动内存管理,垃圾回收功能 3.数组下标越界检查 4.多态 比较: JVM,JRE,JDK...
  • Java虚拟机线程是通过各个线程的轮流切换并分配处理器执行时间(cpu时间片)来实现,同一时间处理器 只能执行一条线程,为了线程切换后可以恢复到原来执行位置,每条线程需要一个独立程序计数器,各个线程...
  • 线程私有区域: 程序计数器: 程序计数器是一块较小内存空间,它可以看做是当前线程所执行字节码行号指示器。 Java虚拟机栈: 每个方法执行同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、...
  • 其中,一部分是线程私有的部分,另外一部分是线程共享的部分。 文章目录Java内存模型之线程私有部分Java内存模型之线程共享部分 Java内存模型之线程私有部分 私有部分为:程序计数器、虚拟机栈、本地方法栈 程序...
  • 私有:程序计数器、java虚拟机栈、本地方法栈 程序计数器:当前线程所执行字节码行号指示器。通过改变这个计数器值来选取下一条需要执行字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要...
  • 线程私有数据区域生命周期与线程相同, 依赖用户线程启动/结束而创建/销毁(在Hotspot VM内, 每个线程都与操作系统本地线程直接映射, 因此这部分内存区域的存/否跟随本地线程生/死)。 1.Native Method Stack本地...
  • java堆区是用于存储对象实例一块内存,同时也是垃圾回收器执行重点区域,因为堆区是垃圾回收器重点回收区域,所以gc极有可能会在大内存使用和回收工作上称为性能瓶颈。为了解决这个问题,JVM考虑是否一定会
  • 基础知识根据前面学到的Java内存模型理论知识,我们来... 根据Java内存运行时数据分配,静态变量存于方法区中,实例对象存于堆中,此二区域为线程共享,而方法中变量存于虚拟机栈,为线程私有。对象状态可能包...
  • Java Virtual Machine=JVM 虚拟机内存空间...先介绍线程私有区: 这里说的线程私有区,顾名思义,就是多线程中各个线程独立使用内存空间,包括: 程序计数器: 在多线程编程中,存在上下文切换现象(每条线程...
  • 程序计数器:一块内存区域,记录当前线程要执行的指令地址,并且是私有的。(因为Cpu是时间片的执行各个线程的代码,所以必须有一个程序计数器记录当前代码的执行情况,如果执行是native 方法,pc计数器记录的是...
  • 总结 : 进程间是互相独立,线程间是共享进程空间,所以线程会有并发问题.JVM运行时数据区域线程私有 : 程序计数器,虚拟机栈,本地方法栈线程共享 : 堆,方法区,直接内存程序计数器主要有2个作用...
  • java线程

    2018-06-27 22:03:42
    进程还拥有一个私有的虚拟地址空间,该空间仅能被它所包含的线程访问。可以看成是轻量级的进程,是CPU调度和分派的基本单位。区别1、调度 :从上面的定义可以看出一个是调度和分派的基本单位,一个是拥有资源的基本...
  • 思考来自于汤子瀛操作系统第四版,79页,我觉得结合java虚拟机里面线程共有区域的模型,一开始我推测是用户级线程,也就是进程对外获取资源,内部分线程共有区和线程私有区等等.. 但是我突然想到了一个特性,就是...
  • 背景知识:[java虚拟机]--(1)java内存区域--(1)线程私有区域虚拟机内存之线程间共享区域:1、堆 谈及内存区域的划分,一般会将内存区域简单划分为堆内存和栈内存。当然,这只是一种粗粒度划分,详细划分见...
  •  在运行java程序时,Java虚拟机需要使用内存来存放各种...运行时数据区可以分为两类:一类是多个线程共享的,另一类是线程私有的。多线程共享的运行时数据区需要在java虚拟机启动时创建,在java虚拟机退出时销毁...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,932
精华内容 1,572
关键字:

java线程私有的区域

java 订阅