Git -- 有趣的命令
本文主要介绍一些我在日常开发中觉得比较有趣的Git基础命令
差异对比日常开发中,差异对比是执行比较频繁的命令HEAD一般指向当前分支的最后一次Commit,下面三种是我最常用的差异对比
git diff尚未暂存的Working Tree与HEAD的差异
git diff –cachedIndex与HEAD的差异注 : 别名git diff --staged
git diff HEAD尚未暂存的Working Tree + Index与HEAD的差异
操作实例12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455$ gst -sb## master$ lsREADME.md$ echo 'Hello' >> README.md$ gst -sb## master M README.md$ git diffdiff --git a/README.md b/README.mdindex e69de29..e965047 10064 ...
JVM基础 -- 类初始化
本文主要关注类加载过程中的类初始化阶段,介绍clinit方法、主动引用和被动引用
clinit类(接口)初始化阶段是执行**clinit**方法的过程
接口 clinit
接口的clinit方法主要用于在接口初始化时,**初始化接口的域**(默认是public static final)
编译后,接口中的域,有些会在Class文件常量池中,有些在clinit方法中进行初始化
代码1234567public interface InterfaceClinit { class InnerClass { } InnerClass INNER_CLASS = new InnerClass(); String NAME = "zhongmingmao";}
字节码1234567891011121314151617181920public static final me.zhongmingmao.class_initialization.InterfaceClinit$InnerClass INNER_CLASS; de ...
JVM基础 -- 晋升规则
本文将通过最基本的垃圾收集器(Serial + Serial Old),简单地讲述JVM内存分配和回收过程中的3个基本的晋升规则:大对象直接晋升、对象年龄晋升、动态晋升代码托管在:https://github.com/zhongmingmao/jvm_demo
-XX:+UseSerialGC
新生代采用Serial垃圾收集器(Copying算法,单线程,Stop The World)
老年代采用Serial Old垃圾收集器(Mark-Compact算法,单线程,Stop The World)
Minor GC / Major GC / Full GC常规理解
Eden空间不够 ➔ Minor GC ➔ 回收Young Generation
Old Generation空间不够 ➔ Major GC ➔ 回收Old Generation
Method Area(Java 8开始由MetaSpace实现,之前由Permanent Generation实现)空间不够 ➔ Full GC ➔ 回收Young Generation+Old Generation+Method Area
...
JVM基础 -- 伪泛型
本文将从JVM字节码的角度解释一下Java为什么是伪泛型
伪泛型
Java是伪泛型的,泛型在Java中只是语法糖,是通过类型擦除和强制转换来实现的
在运行期,ArrayList<Integer>与ArrayList<String>就是同一个类,在Java中并不存在类似与ArrayList<Integer>这种泛型类型
代码1234567891011121314151617181920public class FakeGeneric { static class Father { } static class Son extends Father { } private static void checkFather(Father father) { } public static void main(String[] args) { Map<Father, Father> map = new HashMap<&g ...
JVM基础 -- 方法重载 + 方法重写
本文将从JVM字节码的角度解释方法重载与方法重写
方法重载代码12345678910111213141516171819202122232425262728293031323334package me.zhongmingmao.test;public class StaticDispatch { interface Human { } static class Man implements Human { } static class Woman implements Human { } public static void sayHello(Human human) { System.out.println("Hello , I'm a human"); } public static void sayHello(Man man) { System.out.println("Hel ...
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 ...