Java 静态块到底在什么时候被调用(如何确定一个class是否被classloader加载)

Submitted by Lizhe on Tue, 05/16/2017 - 17:21

今天在项目的老代码里debug , 发现有一个获取ESB对象的初始化动作写在了静态块里

结果debug一直到使用这个类的时候这段代码才被执行到

这些年一直用spring, 主观上认为单例模式跟静态块在缓存这个层面上差不多,也没有深究过

一直觉得静态块跟spring的单例对象差不多, tomcat容器在启动时就应该被调用, 实际上并非如此

class只有在第一次被调用时才会被classloader加载, 当class被加载后static块才会被调用

为了证实这种猜测,我们使用一个简单例子做验证

我尝试使用jconsole查看classloader, 跟本地jvm加上

-Djava.rmi.server.hostname=10.10.8.57

-Dcom.sun.management.jmxremote  

-Dcom.sun.management.jmxremote.port=8011

-Dcom.sun.management.jmxremote.ssl=false

-Dcom.sun.management.jmxremote.authenticate=false

如何选择GC算法

Submitted by Lizhe on Tue, 05/16/2017 - 16:24

对于几种GC垃圾收集器的介绍请参阅

http://lizhe.name.csdn.net/node/89

1. Serial

虽然也是分代收集器但是单线程, 运行时阻塞全部进程, 适用场景非常有限,一般用于单核cpu并且堆小于100M的场景

2. Throughput

是Serial的升级版本, 多线程, 是server模式的默认配置, 有富裕的cpu内核的话, 这个版本即使在堆内存小于100M的情况下也比Serial提供了更好的性能

如果堆小于4GB, 这个配置比较中庸一点

如果是运行batch批处理程序, 当batch能够吃掉所有cpu内核时(有足够多的线程或者cpu没有多余的内核提供给jvm), throughput往往可以比CMS提供更好的性能

因为它可以更长时间的保证cpu在100%占用率的情况下工作

如果是运行web应用, 当cpu没有多余内核时, throughput仍然能提供更好的性能. 这是因为如果CMS得倒的cpu资源受限,CMS收集器会发生并发失效的情况,这时候它会使用单线程Full GC

3. CMS

Java 垃圾回收机制

Submitted by Lizhe on Tue, 05/16/2017 - 11:35

Java如何进行GC已经是一个老话题了

这里我们分成两个部分讨论  一是回收方式(引用计数器或者移动对象方式等) ,二是GC算法(Concurrent或者非Concurrent等)

通常情况下要进行GC就要知道 

1. 哪些对象需要回收 (标记空对象)

2. 如何重新分配内存 (先释放对象,然后整理压缩内存空间)

现代jvm几乎都使用了分代回收的方式 (即划分成新生代和老生代) , 通过对象的年龄(第一次回收存活的对象年龄为1,第二次仍然存活为2,依次类推)来处理对象是该处在新生代还是老生代

回收新生代的GC称为 Minor GC , 类似BigDecimal这种创建之后无法修改,而又经常需要丢弃的临时对象往往都是被Minor GC回收掉的

当对象不停的被移动到老生代, 老生代填满之后需要进行Full GC

两种GC方式都需要暂停所有线程, jvm会进入一种"假死"的状态等待本次GC运行完成

那么有没有什么方法可以缩短这种"假死"状态的时间呢?

答案是 "在线程运行期间就开始查找整理不在使用的可回收对象" , 

JIT 编译器 2

Submitted by Lizhe on Mon, 05/15/2017 - 11:31

 

-XX:ReservedCodeCacheSize=1024m 可以帮助设置JIT编译的本地代码的最大容量

你可以简单的改大这个值以获取更多的本地代码空间, 不过内存始终是一种有限资源, 也可以通过编译阀值来控制编译行为

影响编译阀值的最主要因素是代码的执行频率,一旦执行达到了一定次数,就达到了编译阀值,编译器就可以获取足够的信息然后编译代码了

jvm通过两种值来确定代码的执行频率的

1. 方法调用计数器, 也就是方法被调用了多少次

2. 方法中的循环回边计数器, 也就是方法中的for或者while的运行次数, 全部循环结束或者continue都算做完整的循环回边

如果一段代码达到了编译条件, 就会被送进编译队列.

但是还有一种极端情况例如while(true), 这种循环永远不会退出, jvm会在其不中断运行的情况下直接stack上的代码(On-Stack Replacement, OSR)

普通的编译触发可以通过-XX:CompileThreshold=N修改, client的默认值是1500, server的默认值是10000

OSR的阀值不同由公式

JIT 编译器

Submitted by Lizhe on Sun, 05/14/2017 - 20:22

 

JIT编译器 ( Just-In-Time ) , 是保证java程序运行性能的核心概念.

我们说C++之类的语言是编译型语言,而php或者perl之类的脚本语言一般为解释型语言

对于只运行一次的代码, 解释型语言更为灵活也更快, 因为节约了预处理(编译链接之类)的步骤

对于运行多次的代码, 编译型语言则更快(二进制码的运行速度要优于可读代码)

这里我们知道java实际上是一种混合语言,它会把java代码先编译成字节码,然后在jvm上运行, 但是实际上jvm运行的也不全是java字节码,对于调用次数最多的一些代码,jvm会在运行多次以后将其编译成跟C++一样的二进制码,从而达到更快的运行速度

这里不同的jvm虚拟机的处理方式是不一样的, Oracle的HotSpot JVM只会将"最热"的一部分代码进行彻底编译

1. 编译器的类型

编译器的类型分为两种, 一种是client 另一种是server

你需要使用 java -client 或者 java -server 来使用它们

两种编译器的主要区别在于编译代码的时机不同(这里指的是编译成为二进制码的时机而不是javac编译字节码的时机)

Angularjs1 教程3

Submitted by Lizhe on Fri, 05/12/2017 - 09:56

 

本章讨论如何与服务器通信

还记得07年ajax刚开始火(也可能是年少无知的我刚知道它很火 =。= )

你需要创建xmlhttprequest对象,创建之前还要判断浏览器,然后判断服务器返回的状态码...balabala

然后知道了phototype, 接着是万能的jquery, 估计现在大多数人一提到ajax想到的都是jquery

言归正传, 要使用angularjs1 发送http请求你需要... $http服务(这是一个angularjs1的亲儿子,核心服务)

直接上代码没啥好说的

Angularjs1 教程2

Submitted by Lizhe on Thu, 05/11/2017 - 13:34

这篇文章就是一个angularjs1的大杂烩, 讨论了以下问题

1. 如何在一个页面上启动两个module

2. angular.module 方法 与 ng-app 的关系

3. 如何安全的使用controller注入依赖

4. factory, service, provider的区别

5. 模块之间的依赖关系和加载顺序

 

如果需要启动两个app , 可以使用如下结构

这里需要注意的是,

是 var app1 = angular.module("app1",[]); 先创建了一个名叫app1 的模块, 然后<div ng-app="app1">去引用这个模块

所以当只有var app1 = angular.module("app1",[]); 不会报错,只是没有引用

如果只有<div ng-app="app1">会出现找不到模块的错误

The Tower of HANOI

Submitted by Lizhe on Wed, 05/10/2017 - 15:59

汉诺塔问题经常被用于递归的教学,当然还有一个印度传说

在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

这里纯粹是无聊重新研究一下

先考虑一下"小"问题

先假设如果有1块disk,当然只需要1步就可以结束整个过程,我们用T1来表示总共需要的步数 T1 = 1

如果有2块disk, 很容易想到是 T2 = 3 (自己脑补一下过程)

3块的时候一共需要7步, T3 = 7 (还是自己脑补)

然后考虑"大"一点

按照前面的经验,

首先需要把除了最大的一个disk之外的所有disk都移动到中间  Tn-1

然后移动最大的一块, T1 ( 也就是1 )