JVM基础 -- JVM字节码执行过程
本文将通过是实例简单介绍JVM字节码基于栈的执行过程
Stack Frame
一个方法从调用到执行完成,对应着一个栈帧(Stack Frame)在虚拟机栈(VM Stack)里面从入栈到出栈的过程
在编译成字节码期间,栈帧需要多大的局部变量表(Local Variable Table),多深的操作数栈(Operand Stack)都已经完全确定,并且写入到方法表的Code属性中
在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧,与这个栈帧关联的方法称为当前方法
局部变量表
用于存放方法参数和方法内部定义的局部变量
方法表中的locals属性记录了局部变量表的最大容量
局部变量表的存储单元为32-bit的slot,boolean、byte、char、short、int、float等会占用一个slot,long和double会占用两个slot
如果执行的是实例方法,那么第0个slot默认存储this
为了节省栈帧空间,slot是可重用的
操作数栈
方法表中的stack属性记录了操作数栈的最大深度
操作数栈可以容纳任意的Java数据类型,32-bit数据类型所占用的栈容量为1,64-bit数据 ...
JVM基础 -- JOL使用教程 3
本文将通过JOL分析Java对象的内存布局,包括伪共享、DataModel、Externals、数组对齐等内容代码托管在https://github.com/zhongmingmao/java_object_layout
伪共享Java8引入@sun.misc.Contended注解,自动进行缓存行填充,原始支持解决伪共享问题,实现高效并发,关于伪共享,网上已经很多资料,请参考下列连接:
https://yq.aliyun.com/articles/62865
http://www.cnblogs.com/Binhua-Liu/p/5620339.html
http://blog.csdn.net/zero__007/article/details/54951584
http://blog.csdn.net/aigoogle/article/details/41517213
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/tip/src/share/classes/sun/misc/Contended.java
代码12345678910111213 ...
JVM基础 -- JOL使用教程 2
本文将通过JOL分析Java对象的内存布局,包括Throwable、Class、Object Header、HashCode等内容代码托管在https://github.com/zhongmingmao/java_object_layout
Throwable代码12345678// JVM Args : -Djol.tryWithSudo=truepublic class JOLSample_07_Exceptions { public static void main(String[] args) throws Exception { out.println(VM.current().details()); out.println(ClassLayout.parseClass(Throwable.class).toPrintable()); }}
运行结果1234567891011121314151617# Running 64-bit HotSpot VM.# Using compressed oop with 3 ...
JVM基础 -- JOL使用教程 1
本文将通过JOL分析Java对象的内存布局,包括基本使用、字节对齐、实例域重排序、继承、继承栅栏、继承对齐等内容代码托管在https://github.com/zhongmingmao/java_object_layout
Maven依赖12345<dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.8</version></dependency>
基本使用代码123456789101112// JVM Args : -Djol.tryWithSudo=truepublic class JOLSample_01_Basic { public static void main(String[] args) throws Exception { out.println(VM.current().details()); o ...
JVM基础 -- Instrumentation + sa-jdi 实例分析
本文将通过Instrumentation + sa-jdi来分析几个实例的内存对象布局
关键概念
Java对象的内存布局:对象头(Header) + 实例数据(Instance Data) + 对其填充(Padding)
Header具体内容
Mark Word:存储对象hashCode、锁信息等
Class MetaData Address:存储对象类型数据的指针
Array Length:数组的长度(如果当前对象是数组,否则没有这一内容)
HotSpot JVM中对象的对齐方式:8字节对齐
实例域重排序:为了节省内存空间,实例域将按(double/long,int/float,short/char,boolean/byte,reference)进行重排序
非静态内部类:有一个隐藏的对外部类的引用
指针压缩:影响对象的内存布局,JVM参数:-XX:+UseCompressedOops
指针压缩的影响
是否开启压缩
Mark Word
Class MetaData Address
Reference
否
8
8
8
是
8
4
4
指针压缩代码123456public cla ...
JVM基础 -- Instrumentation + sa-jdi 工具构建
本文首先介绍测量对象内存布局的其中一种方法,Instrumentation + sa-jdi
核心代码
代码托管在:https://github.com/zhongmingmao/java_object_layout
采用Instrumentation + sa-jdi的方式需要自己编写代码,比较繁琐,OpenJDK提供的JOL (Java Object Layout) 工具则是开箱即用,非常方便,后续博文会进一步介绍JOL的使用
测量对象大小通过Instrumentation测量对象占用的空间大小
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293/** * 对象占用字节大小工具类<br/> * see http://yueyemaitian.iteye.com/blog/2033046 ...
JVM基础 -- VirtualMachineError实例
VirtualMachineError有两个常见的实现类:StackOverflowError、OutOfMemoryError,本文将用代码分析几种情况的VirtualMachineError
JVM参数
内存区域
虚拟机栈VM Stack
堆Heap
方法区Method Area
共享/隔离
线程隔离
线程共享
线程共享
存放的数据
栈帧 Stack Frame
对象实例/数组
类信息、常量、静态变量等数据
异常情况
StackOverflowErrorOutOfMemoryError
OutOfMemoryError
OutOfMemoryError
JVM参数
-Xss
-Xms-Xmx
-XX:PermSize-XX:MaxPermSize-XX:MetaspaceSize-XX:MaxMetaspaceSize
注:在JDK8之前,Hotspot JVM采用永生代(Permanent Generation)来实现方法区(Method Area),从JDK8开始,已经移除了永生代,使用Metaspace进行替代,相关连接请参考:
http:/ ...
Vim -- 文件
本文将介绍Vim中的文件
基础文件、缓冲区和编辑会话文件:存储在磁盘上缓冲区:存在于内存中编辑会话:执行一次vim命令,默认显示第一个文件的缓冲区,其他文件的缓冲区为后台缓冲区
缓冲区列表一次编辑会话可以在多个缓冲区上工作,这多个缓冲区就是缓冲区列表
123456789101112131415161718192021222324252627# 展示缓冲区列表:ls:列出所有被载入到内存中的缓冲区列表 -:非活动的缓冲区 a:激活的缓冲区 h:隐藏的缓冲区 =:只读的缓冲区 +:已经修改但尚未写入磁盘的缓冲区 #:轮换缓冲区,通过<C-^>切换成当前缓冲区 %:当前缓冲区,通过<C-^>把当前缓冲区切换成轮换缓冲区 <C-^>:#与%切换# 遍历缓冲区列表bp[rev]:上一个缓冲区bn[ext]:下一个缓冲区bf[irst]:第一个缓冲区bl[ast]:最后一个缓冲区b[uffer] {N}:直接跳转到第{N}个缓冲区,例如:b 3b[uffer] {bufferNam ...
Vim -- 命令行模式
本文将介绍Vim中的命令行模式
基础8种模式
普通模式:Vim的自然放松状态,也是Vim的默认模式;操作符和动作命令结合在一起;操作 = 操作符 + 动作命令
插入模式:与Sublime Text默认模式类似
插入-普通模式:这是普通模式的一个特例,让我们从插入模式执行一次普通模式命令,然后回归插入模式,按键为<C-o>
替换模式:与插入模式的区别:在替换模式中输入会替换文档中的已有文本
虚拟替换模式(推荐):制表符当成一组空格进行处理,假设制表符列宽为8,输入的前7个字符时,每个字符会被插入到制表符之前,当输入第8个字符时,该字符会替换制表符
可视模式:允许我们选中一块文本区域并在其上进行操作;面向字符(v)、面向行(SHIFT+v)、面向列(<C-v>)
选择模式:与Word和Sublime Text的操作模式类似,当选中一段文本后,再输入任何可见字符,选择的文本会被删除
命令行模式:行编辑器ex是vi的先祖,vim支持Ex命令
模式切换
常用Ex命令操作缓冲区文本的常用Ex命令(完整列表:h ex-cmd-index)[range]:连续的行
1234567 ...
Vim -- 可视模式
本文将介绍Vim中的可视模式
基础可视模式Vim的可视模式允许我们选中一块文本区域并在其上进行操作
语法规则与普通模式的语法规则次序颠倒普通模式的语法规则:{operator}{motion}可视模式的语法规则:先选中选区,再触发可视命令;类似于典型文本编辑器的操作模式
选择模式典型文本编辑器的操作模式:当选中一段文本后,再输入任何可见字符,选择的文本会被删除可视模式和选择模式相互切换:<C-g>
123456:help Select-mode8. Select mode *Select* *Select-mode*Select mode looks like Visual mode, but the commands accepted are quite different. This resembles the selection mode in Microsoft Windows.When the 'showmode' option is s ...