本地线程

java虚拟机理解探索1

早过忘川 提交于 2020-02-15 22:50:04
以下内容源于个人对《深入java虚拟机》的理解总结 基本概念: java虚拟机可以指一种抽象规范,也可以指一种具体实现,亦可以指一个java虚拟机实例。 虚拟机生命周期: 一个java虚拟机实例的天职是:负责运行一个java程序。当启动一个java程序时,一个虚拟机实例诞生。程序关闭退出,虚拟机实例亦随之消亡。如果在同一台计算机上运行三个java程序,将得到三个java虚拟机实例。每个java程序都运行与它自己的java虚拟机实例中。 一个java虚拟机实例通过调用main()方法来运行一个java程序。 垃圾收集 垃圾收集器的主要工作就是自动回收不再被运行的程序引用的对象所占的内存。此外它也可能去移动那些还在使用的对象,以此减少碎片。 在谈论垃圾回收前,首先了解下java虚拟机的内部体系结构,如下图所示 中间虚线框部分为运行时数据区域,由5部分组成,分别为方法区,堆,栈,程序计数器及本地方法栈。 1.程序计数器 对于一个运行中的java程序而言,其中每一个线程都有自己的PC寄存器,它是该线程启动时创建。 它的作用可以看做当前字节码执行的位置指示器。 2.本地方法栈 任何本地方法接口都会使用本地方法栈。当线程调用本地方法时,虚拟机会创建一个新的栈帧并压人java栈,然而当它调用的是本地方法时,虚拟机会保持java栈不变,不再在线程的java栈中压人新的帧。虚拟机只是简单的动态连接

深入理解java虚拟机读书笔记1--java内存区域

耗尽温柔 提交于 2020-02-15 21:08:28
  Java在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途、创建和销毁的时间,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,有些则是与线程一一对应,随线程的开始和结束而创建和销毁。 Java虚拟机所管理的内存将会包括以下几个运行时数据区域: 1 程序计数器   它是一块较小的内存空间,它的作用可以看做是当先线程所执行的字节码的信号指示器。   java虚拟机的多线程是通过轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储。   此内存区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError的区域。 2 java虚拟机栈   与程序计数器一样,java虚拟机栈也是线程私有的,它的生命周瑜与线程相同。虚拟机栈描述的是java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。   在这里指出一下,经常说的java内存区分为堆内存(Heap)和栈内存(Stack),这种分法太粗糙。   局部变量表存放了编译器可知的各种基本数据类型(boolean、byte

虚拟机内存结构

喜夏-厌秋 提交于 2020-02-15 20:34:04
JVM的主要结构如下图所示,图片引用自 舒の随想日记 。 方法区和堆由所有线程共享,其他区域都是线程私有的 程序计数器(Program Counter Register) 类似于PC寄存器,是一块较小的内存区域,通过程序计数器中的值寻找要执行的指令的字节码,由于多线程间切换时要恢复每一个线程的当前执行位置,所以每个线程都有自己的程序计算器。这一个区域不会有OutOfMemeryError。当执行Java方法时,这里存储的执行的指令的地址,如果执行的是本地方法,这里的值是Undefined。 虚拟机栈(Java Stack) 虚拟机栈也是线程私有的,每创建一个线程,虚拟机就会为这个线程创建一个虚拟机栈,虚拟机栈表示Java方法执行的内存模型,每调用一个方法,就会生成一个栈帧(Stack Frame)用于存储方法的本地变量表、操作栈、方法出口等信息,当这个方法执行完后,就会弹出相应的栈帧。 如果请求的栈的深度过大,虚拟机可能会抛出 StackOverflowError 异常,如果虚拟机的实现中允许虚拟机栈动态扩展,当内存不足以扩展栈的时候,会抛出 OutOfMemoryError 异常。 栈帧(Stack Frame) 栈帧分为三部分:局部变量区(Local Variables)、操作数栈(Operand Stack)和帧数据区(Frame Data)。 局部变量区(Loca

JVM 内存分析

故事扮演 提交于 2020-02-15 20:24:16
简述JVM垃圾回收机制 垃圾回收机制时Java提供的自动释放内存空间的机制. 垃圾回收机制时JVM自导的一个线程,用于回收没有被引用的对象. JVM有一个运行时的数据区来管理内存.其主要包括五大部分:程序计数器,虚拟机栈,本地方法栈,方法区,堆. 其中程序计数器,虚拟机栈,本地方法栈 每个线程私有的内存空间,和线程的生命周期相同.如栈中每个栈帧分配多少的内存基本上在类结构确定时就以几个确定了.无需考虑内存回收的问题. 方法区和堆就和上面不一样了,一个接口的多个类实现需要的内存可能不一样,只有在程序运行期才指导会创建哪些对象,这部分内存的分配和回收都是动态的, GC主要关注的就是该部分内存. Java虚拟机数据区域 黄色: 由所有线程共享的数据区. 绿色: 线程隔离的数据区. 程序计数器:当前线程所执行的字节码的行号指示器,在虚拟机的概念模式里,字节码解释器工作就是通过改变程序计数器的值来选择下一跳需要执行的字节码指令,分支,循环,跳转,异常处理,线程回复等基础功能都要依赖这个基础器来完成. Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,指挥执行一条线程中的指令.因此,为了线程切换之后能够恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线成之间的计数器互不影响,独立存储. 如果线程正在执行一个Java方法

JVM参数配置

心不动则不痛 提交于 2020-02-13 20:45:52
新生代配置 新生代大小配置参数的优先级: 高: -XX:NewSize/MaxNewSize 中间 -Xmn ( NewSize= MaxNewSize ) 低: -XX:NewRatio 表示比例,例如 =2 ,表示 新生代:老年代 = 1:2 -XX:SurvivorRatio 表示 Eden 和 Survivor 的比值, 缺省为 8 表示 Eden:From Survivor:ToSurvivor= 8:1:1 同样的代码情况下: -Xms20M -Xmx20M -XX:+PrintGCDetails –Xmn2m -XX:SurvivorRatio=2 没有垃圾回收 数组都在老年代 -Xms20M -Xmx20M -XX:+PrintGCDetails -Xmn7m -XX:SurvivorRatio=2 发生了垃圾回收 新生代存了部分数组,老年代也保存了部分数组,发生了晋升现象 -Xms20M -Xmx20M -XX:+PrintGCDetails -Xmn15m -XX:SurvivorRatio=8 新生代可以放下所有的数组 老年代没放 -Xms20M -Xmx20M -XX:+PrintGCDetails -XX:NewRatio=2 发生了垃圾回收 出现了空间分配担保,而且发生了 FullGC JDK 为我们提供的工具 jps 列出当前机器上正在运行的虚拟机进程

synchronized

女生的网名这么多〃 提交于 2020-02-12 04:55:39
首先讲一下原子性以及互斥。 举个例子,在32位CPU上执行long(64位)变量的写操作时,会存在多线程下读写不一致的问题。 因为32位CPU下对其写会拆分成两次操作,一次写高32位和一次写底32位,而这个操作无法保证其 原子性 所以产生并发问题了。 原子性 指即一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行,简单的说就是一个或者多个操作在 CPU 执行的过程中不被中断的特性。 互斥 如果 同一时刻只有一个线程执行 则被称之为 互斥 ,把一段需要互斥执行的代码称为 临界区 。如果我们能够保证对共享变量的修改是互斥的,那么,无论是单核 CPU 还是多核 CPU,就都能保证原子性了。 互斥锁 锁是一种通用的技术方案,Java 语言提供的 synchronized 关键字,就是一种互斥锁。synchronized 关键字可以用来修饰方法,也可以用来修饰代码块,通过其修饰的临界区是互斥的,使用方法如下: public class demo{ private final Object monitor = new Object(); // 修饰非静态方法 synchronized void method1() { // 临界区 } // 修饰静态方法 synchronized static void method2() { // 临界区 } // 修饰代码块

JVM-GC调优,一文详解JDK监控和故障处理命令及常见故障分析

时光总嘲笑我的痴心妄想 提交于 2020-02-10 20:42:15
本文转载自: JVM-GC调优,一文详解JDK监控和故障处理命令及常见故障分析 JVM 的定位系统问题时,知识和经验是关键基础,数据是依据、工具是运用知识处理数据的手段 数据包括:运行日志、异常堆栈、GC日志、线程快照(thread dump、javacore文件)、堆转储快照(headdump / hprof 文件) 一、调优命令 JDK监控和故障处理命令,在bin目录下有: jps、 jstat、jmap、jhat、jstack、jinfo jps:显示虚拟机进程,常用如: jps -l -v jstat:收集虚拟机各方面的运行数据,常用如: jps-gcutil 2764 、 jstat -gc 2764 250 20 jinfo:显示虚拟机配置信息 jmap:生成虚拟机内存转储快照(headdump 文件),常用如: jmap -dump:live,format=b,file=dump.hprof 28920 jhat:用于分析headdump 文件,他会建立一个http/html 的服务器,让客户可以在浏览器上查看分析结果,常用如: jhat dump.hprof jstack: 显示虚拟机线程快照,常用如: jstack -l 11494 下面做一 一介绍 二、Jps 显示指定系统内所有的HotSpot虚拟机进程, 格式 : jps - [hostid] options

网络IO模型

喜夏-厌秋 提交于 2020-02-10 20:06:58
1、同步网络IO模型      网络IO模型分两段,一个write,一个read,write操作我们不需要考虑,这里我们看read操作。 接受线程会一直阻塞,当有数据到来的时候,操作系统会先把数据写入接收缓存,然后给接收数据的线程发一个通知, 线程收到通知后结束等待,开始读取数据。处理完这一批数据后,继续阻塞等待下一批数据到来,这样周而复始地处理收到的数据。   每个连接都需要阻塞一个线程来等待数据,当大量连接数时就会有大量线程被阻塞,造成CPU负载过高,系统的性能较慢 2、异步网络模型   同步IO导致线程阻塞会影响性能,同时也不能使用极少的线程来处理网络请求,所以我们想到异步网络模型。脑海中想到系统异步设计中,采用非阻塞的模式,当有数据来的时候创建一个线程 来接收数据,这样就可以用少量的线程来处理大量的连接。        1、使用Netty实现网络通信        // 创建一组线性 EventLoopGroup group = new NioEventLoopGroup(); try{ // 初始化Server ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(group); serverBootstrap.channel

java并发编程之Executor线程池

落爺英雄遲暮 提交于 2020-02-10 10:55:01
java并发编程之Executor线程池 1 线程&多线程&进程 a、线程: 线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。 b、多线程: 多线程指在单个程序中可以同时运行多个不同的线程执行不同的任务。多线程编程的目的,其实就是“最大限度地利用 cpu 资源”,当某一线程的处理不需要占用 cpu 而只和 io 等资源打交道时,让需要占用 Cpu 的其他线程有其他机会获得 cpu 资源。从根本上说,这就是多线程编程的最终目的。 c、线程与进程的区别 进程是操作系统分配资源的最小单元,线程是操作系统调度的最小单元。 一个程序至少有一个进程,一个进程至少有一个线程。 2 线程的实现方式 继承Thread类,重写run方法 public class ThreadDemo extends Thread { private static final Logger logger = LoggerFactory . getLogger ( ThreadDemo . class ) ; public static void main ( String [ ] args ) { ThreadDemo

JVM内存模型

寵の児 提交于 2020-02-10 00:57:43
个人博客 http://www.milovetingting.cn JVM内存模型 前言 本文为学习Java相关知识所作笔记,参考以下资料: https://github.com/Snailclimb/JavaGuide ,感谢原作者的分享! 基本概念 JVM是可运行Java代码的虚拟计算机,包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收器、堆和一个存储方法域。JVM运行在操作系统之上,它与硬件没有直接交互。 Java源文件,通过编译器,能够生产相应的class文件,也就是字节码文件,字节码文件通过Java虚拟机中的解释器,编译成特定机器上的机器码。 Java源文件-->编译器-->字节码文件 字节码文件-->JVM-->机器码 每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不能共享。 线程 这里所说的线程指程序执行过程中的一个线程实体。JVM 允许一个应用并发执行多个线程。Hotspot JVM 中的 Java 线程与原生操作系统线程有直接的映射关系。当线程本地存储、缓冲区分配、同步对象、栈、程序计数器等准备好以后,就会创建一个操作系统原生线程。Java 线程结束