本地线程

今天是JVM的生日,来了解下JVM的发展历史吧

血红的双手。 提交于 2019-12-05 19:43:43
1991年4月,由James Gosling主导的团队创造了Oak语言,java的前身,1995年5月23号,Oak语言更名Java,并且提出那句注明的:”write Once,Run Anywhere”的口号.1996年1月23日,JDK1.0发布. 当时正好赶上浏览器快速崛起,发展的浪潮,大家发现java一处编译到处使用的特性和浏览器很契合,同一个页面不可能每一个操作系统我都写一遍.用现在的话说java正好站在这个风口上.导致它飞速发展才有了今天的江湖地位. 一、JVM简介 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。 Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后

Java学习笔记1-JVM原理

£可爱£侵袭症+ 提交于 2019-12-05 16:54:51
Java学习笔记1-JVM原理 class字节码开头0xcafebabe特殊标志 源代码.java 编译 -> 字节码.class -> JVM运行时数据区 线程共享部分 线程独占部分 方法区 虚拟机栈 | 本地方法栈 堆内存 程序计数器 线程独占 :每个线程都会有它独立的空间,随线程生命周期而创建和销毁 线程共享 :所有线程能访问这块内存数据,随虚拟机或者GC而创建和销毁 方法区 :JVM用来存储加载的类信息、常量、静态变量、编译后的代码等数据。虚拟机规范中这是一个逻辑区划。具体实现根据不同虚拟机来实现。如:Oracle(Sun)的HotSpot在java7中方法区放在永久代,java8放在元数据空间,并且通过GC机制对这个区域进行管理 堆内存 :还可以细分为:老年代、新生代(Eden、From Survivor、To Survivor),JVM启动时创建,存放对象的实例,所有实例字段、静态字段和数组元素都存储在堆内存中。垃圾回收器主要就是管理堆内存。如果满了,就会出现OutOfMemroyError 虚拟机栈 :每个线程都在这个空间有一个私有空间。线程栈由多个栈帧(Stack Frame)组成。一个线程会执行一个或多个方法,一个方法对应一个栈帧。栈帧内容包含:局部变量表、操作数栈、动态链接、方法返回地址、附加信息等。栈内存默认最大是1M

JVM集训-----内存结构

旧城冷巷雨未停 提交于 2019-12-05 16:28:24
摘自: https://www.cnblogs.com/lowerma/p/11929041.html JVM集训-----内存结构 一、程序计数器/PC寄存器 ( Program Counter Registe )   用于 保存当前正在执行的程序的内存地址(下一条jvm指令的执行地址) ,由于Java是支持多线程执行的,所以程序执行的轨迹不可能一直都是线性执行。当有多个线程交叉执行时,被中断的线程的程序当前执行到哪条内存地址必然要保存下来,以便用于被中断的线程恢复执行时再按照被中断时的指令地址继续执行下去。为了线程切换后能恢复到正确的执行位置, 每个线程都需要有一个独立的程序计数器 ,各个线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存,是线程安全的。    特点:1.线程私有 2.不会存在内存溢出 二、虚拟机栈(Java Virtual Machine Stack)    虚拟机栈总是与线程关联在一起的, 每当创建一个线程,JVM就会为该线程创建对应的虚拟机栈 ,在这个 虚拟机栈中又会包含多个栈帧(Stack Frame) ,这些栈帧是与每个方法关联起来的, 每运行一个方法就创建一个栈帧 ,每个栈帧会含有一些局部变量、操作栈和方法返回值等信息。每当一个方法执行完成时,该栈帧就会弹出栈帧的元素作为这个方法的返回值,并且清除这个栈帧,

Java并发之volatile关键字

偶尔善良 提交于 2019-12-05 15:47:00
引言 说到多线程,我觉得我们最重要的是要理解一个临界区概念。 举个例子,一个班上1个女孩子(临界区),49个男孩子(线程),男孩子的目标就是这一个女孩子,就是会有竞争关系(线程安全问题)。推广到实际场景,例如对一个数相加或者相减等等情形,因为操作对象就只有一个,在多线程环境下,就会产生线程安全问题。理解临界区概念,我们对多线程问题可以有一个好意识。 Jav内存模型(JMM) 谈到多线程就应该了解一下Java内存模型(JMM)的抽象示意图.下图: 线程A和线程B执行的是时候,会去读取共享变量(临界区),然后各自拷贝一份回到自己的本地内存,执行后续操作。 JMM模型是一种规范,就像Java的接口一样。JMM会涉及到三个问题:原子性,可见性,有序性。 所谓原子性。就是说一个线程的执行会不会被其他线程影响的。他是不可中断的。举个例子: int i=1 这个语句在Jmm中就是原子性的。无论是一个线程执行还是多个线程执行这个语句,读出来的i就是等于1。那什么是非原子性呢,按道理如果Java的代码都是原子性,应该就不会有线程问题了啊。其实JMM这是规定某些语句是原子性罢了。举个非原子性例子: i ++; 这个操作就不是原子性的了。因为他就是包含了三个操作:第一读取i的值,第二将i加上1,第三将结果赋值回来给i,更新i的值。 所谓可见性。可见性表示如果一个值在线程A修改了

【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!

大兔子大兔子 提交于 2019-12-05 13:46:24
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star!【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。觉得内容不错再 Star!)。 另外推荐一篇原创: 终极推荐!可能是最适合你的Java学习路线+方法+网站+书籍推荐! Java 并发进阶常见面试题总结 1. synchronized 关键字 1.1. 说一说自己对于 synchronized 关键字的了解 synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。 另外,在 Java 早期版本中,synchronized属于重量级锁,效率低下,因为监视器锁(monitor)是依赖于底层的操作系统的 Mutex Lock 来实现的,Java 的线程是映射到操作系统的原生线程之上的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高,这也是为什么早期的 synchronized 效率低的原因。庆幸的是在 Java 6 之后 Java 官方对从 JVM 层面对synchronized 较大优化,所以现在的 synchronized

JVM之Java运行时数据区

痴心易碎 提交于 2019-12-05 12:34:10
来源 JVM会在会在执行Java程序过程中把所管理的内存划分为若干区域,主要包括程序计数器(Program Counter Register),虚拟机栈(VM Stack),本地方法栈(Native Method Stack),堆区(Heap)以及方法区(Method Area)。其中前面3个是线程隔离的数据取,即各个线程均有一份,而后两者是共享区,即所有线程均共享同一份。接下来,我们分别来看一下这些区域。 首先是程序计数器。 来源: https://www.cnblogs.com/lbrs/p/11925278.html

JVM的优化

老子叫甜甜 提交于 2019-12-05 12:03:55
jVM组件 类加载器(ClassLoader):加载类 运行时数据区:方法区,虚拟机栈,本地方法栈,堆,程序计数器 执行引擎(面试不聊)翻译成机器语言 本地库接口 :处理其它语言的方法实现 内存如何分配: 方法区:存的是类相关的一些信息(类字节码对象,类变量,类方法)堆:存对象实例,区域最大Java虚拟机栈(栈内存):栈帧(封装了方法和变量)->方法入口(main方法)出口本地方法栈:和Java虚拟机栈概念一样,交给本地系统执行程序计数器:记录程序执行的位置,多线程切换时记录,回到记录点继续运行 线程共享的区(每个线程都可访问,jvm在而在):方法区,堆线程私有的区(不共享,只有自己线程访问,线程销毁而销毁):java虚拟机栈,本地方法栈,程序计数器​1核多线程:争夺CPU时间片,你执行一行,我抢到了我执行一下​栈内存溢出:StackOverOfFlowError 栈装不下,满了内存溢出OOM:OutOfMemoryError 内存不足 无限创建对象或线程​VM-option(分配栈内存空间大小): -Xmx20m 堆最大内存大小 -Xms20m 虚拟机启动初始化堆内存大小,最小堆内存 //在堆内存溢出的时候,我们需要排查占用空间比较大的对象 //分析这个对象是否真的需要 //内存溢出 //内存泄漏其它语言实现的方法由native修饰​垃圾回收主战场:堆,也可以开启对方法区的回收

常见的 由于未调整服务器 ulimit 而引起的内存溢出问题

只愿长相守 提交于 2019-12-05 11:46:54
原文内容来自于LZ(楼主)的印象笔记,如出现排版异常或图片丢失等问题,可查看当前链接:https://app.yinxiang.com/shard/s17/nl/19391737/e3bb62c9-9dd3-4876-a92b-adf939336682 本篇共引起三个问题: 1、ulimit 的调整(否则将默认进程只能创建1024个线程) 2、XSS配置的说明(默认线程为1M,此处配置XSS线程所占用内存为246K) 3、 线程所占用的内存为堆外内存(相比大家也都知晓该问题,本篇也是因为服务内存不足,调整Ulimit后还是存在oom的问题,而最终引起并说明下该线程堆外的问题) 注意:(java中每实例化一个线程,则是向操作系统服务器请求实例化一个本地内存,并非是直接使用的JVM中所配置的堆的内存的大小,,需注意,) 在直接使用线上内存分析时,曾出现类似的一个问题是这样的, 线上服务器共8G内存,通过 ps -ef|grep java,可以查看共部署了3台服务, 前两台robot服务,分别配置Xms为2G,我们的core设置JVM参数为-Xms为3G, 此时则已经吃掉了7G的内存,除去服务器自身再吃掉500M内存,那么此时可供使用的内存仅有 500M左右,而此时服务器频繁报错异常则为, 不能够创建新的本地线程,最初时怀疑是 linux 服务器所设置的 进程可开启线程数较少的原因

多线程之美2一ThreadLocal源代码分析

无人久伴 提交于 2019-12-05 11:32:51
1、应用场景及作用 -1作用、ThreadLocal 为了实现线程之间数据隔离,每个线程中有独立的变量副本,操作互不干扰。区别于线程同步中,同步在为了保证正确使用同一个共享变量,需要加锁。 -2应用场景: 1)可以对一次请求过程,做一个过程日志追踪。如slf4j的MDC组件的使用,可以在日志中每次请求过程加key,方便定位一次请求流程问题。 2)解决线程中全局数据传值问题。 2、结构关系 要理清ThreadLocal的原理作用,可以先了解Thread, ThreadLocal, ThreadLocalMap三者之间的关系。简单类图关系如下 2.1、三者关系类图 1、Thread 类中有ThreadLocalMap类型的成员变量 threadLocals 2、ThreadLocalMap是ThreadLocal的静态内部类 3、Thread 与 ThreadLocal怎么关联? 线程对象中threadLocals中存储的键值对 key--> ThreadLocal对象,value --> 线程需要保存的变量值 2.2、ThreadLocalMap结构图 ThreadLocalMap 底层实现实质是一个Entry对象数组, 默认容量是16,在存储元素到数组中,自己实现了一个算法来寻址(计算数组下标), 与Map集合中的HashMap有所不同。 Entry对象中

java杂记

 ̄綄美尐妖づ 提交于 2019-12-05 10:07:09
/*--> */ /*--> */ 1.stream Map() FlatMap()区别 map: 对于Stream中包含的元素使用给定的转换函数进行转换操作,新生成的Stream只包含转换生成的元素。 flatMap:和map类似,不同的是其每个元素转换得到的是Stream对象,会把子Stream中的元素压缩到父集合中。 下面这张图比较直观 跑一下,注意标红: 2.wait() notify() notifyAll() 语法 场景 wait()、notify()、notifyAll()必须在同步块/同步方法内执行,因为只有在调用线程在获得对象的锁时,才能调用对象的wait()、notify()、notifyAll()方法,如果在未获得对象的锁的情况下调用对象的这三个方法,将抛出IllegalMonitorStateException异常。 3.Redis Aof Rdb 持久化区别 RDB持久化在指定时间间隔内生成数据集的时间点快照。 优点:保存某个时间点的数据集,适合备份,恢复数据集的速度快。 缺点:数据量大时,保存速度慢,如果快照频率慢,故障停机时,可能会丢失大量数据。 AOF持久化记录服务器所执行的所有写操作,通过重新执行命令还原数据集。 优点:AOF使redis非常耐久,可设置不同的fsync策略,AOF文件是一个只进行追加操作的日志文件,故障停机时,丢失数据量小。 缺点