0007JDK源码分析之揭秘整数常量池实现机制

Posted Java框架源码分析

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0007JDK源码分析之揭秘整数常量池实现机制相关的知识,希望对你有一定的参考价值。

本文将介绍整数常量池的实现机制,池是一种缓存策略,恰当的运用有利于提供性能。

本文大纲:

一、为什么要整数常量池?

二、整数常量池在哪里?

三、如何使用整数常量池?

四、总结

一、为什么要整数常量池?

在开发程序时,我们经常要使用到整数,JDK提供的整数类型分为两种,一种是原生的,比如:byte,short,int,long。另外一种则是对应原型类型的对象类型,比如:Byte,Short,Integer,Long。如果我们每创建一个整数类型对象都要重新new的话,很明显是会占用很多无谓的内存空间,即使很快会被GC回收。但是如果是一些类似数据库连接对象,频繁创建,则可能会带来性能瓶颈,所以我们使用数据库连接一般都是使用连接池技术。

二、整数常量池在哪里?

整数常量池位于类的内部,是使用私有静态内部类来实现的,Byte、Short、Integer以及Long类内部都有常量池,缓存的对象是-128~127之间的整数。Boolean类也使用了缓存,使用的是final static缓存了两个对象常量属性,相对于整数产量池简单很多,那静态的内部类又是如何实现缓存的呢?Byte、Short、Integer以及Long的缓存实现如下:

【0007】JDK源码分析之揭秘整数常量池实现机制

【0007】JDK源码分析之揭秘整数常量池实现机制

【0007】JDK源码分析之揭秘整数常量池实现机制

三、如何使用整数常量池?

细心观察的朋友,可能会发现这个整数常量池的内部类是private的,也就是说只能在该类所属的类中使用,这也是符合常理的,我们客户端创建对象的时候,并不关注被创建对象内部是如何创建对象的,只要返回对象实例到客户端即可。整数常量池其实就是预先创建一组对象,缓存起来,客户端重复创建一个对象的时候,就可以从池中取出,不用重复创建,提供了性能。那么,我们直接new对象,真的是常量池中的对象吗?不是。比如我们new Integer(100),并不会从常量池中拿的,而是一个新的对象。只有我们通过Integer.valueOf(100)这种方式来获取对象实例的时候,才会从常量池中拿,才会真正的节省资源空间。Byte、Short、Long也有同样的方法提供来获取对象实例,建议使用此方法来获取整数的对象实例。其实,也只有这种方式获取对象才能使用到整数常量池。Integer类的valueOf()方法实现如下:

四、总结

本文介绍了整数常量池的由来,实现机制,以及如何使用正确的API来使用整数常量池,真正的减少对象的创建。从开发者的角度看整数常量池,我们创建对象的使用valueOf()方法就可以使用到了常量池,但前提是整数范围位于-128到127之间。从设计者的角度看常量池,三个方向,一:为什么要使用池?二:如何实现池?三:如何使用池?打个比方,开发者平时频繁的创建很多小的整数的对象,自然会浪费很多资源空间,这时候就可以使用池,这是为什么。如何实现呢?使用静态内部类,提前创建好客户端会频繁创建的对象实例。这仅仅是一种缓存的策略,还有很多其它的缓存策略。最后是怎么使用池?提供一个静态的工厂方法的API让客户端调用。

感谢你的阅读,谢谢!

以上是关于0007JDK源码分析之揭秘整数常量池实现机制的主要内容,如果未能解决你的问题,请参考以下文章

线程池源码分析之ThreadPoolExecutor

0013JDK源码分析之枚举

jdk源码分析——String类

Dubbo源码分析之ExtensionLoader加载过程解析

JDK动态代理[2]----JDK动态代理的底层实现之Proxy源码分析

Dubbo底层源码分析之SPI扩展点