Gude Blog


  • 首页

  • 关于

  • 归档

  • 标签

java4种引用

发表于 2017-12-09

今天在看HikariCP源码ConcurrentBag类时,发现它里面使用了WeakReference,第一次看到这个,之前从来没用过,于是查资料去了解下。

引用类型

Java中一共有4中引用,分别为强引用(Strong Reference)、软引用(Soft Reference、弱引用(Weak Reference)、虚引用(Phantom Reference),强度依次递减。

强引用

java的默认实现,类似Object obj=new Object(),它会尽可能长时间存在于JVM,当没有任何对象指向它的时候才会被GC回收

1
2
3
4
5
6
7
8
9
10
11
@Test
public void strongRefTest(){
Object obj=new Object();
Object strongRef=obj;
obj=null;
System.gc();
/***
* GC后不会被回收
*/
assertNotNull(strongRef);
}

阅读全文 »

Datasource和DriverManager获取Connection的区别

发表于 2017-12-03
  • Datasource是一个接口,DriverManager是具体的类。接口可以很多种实现方式,这正是java多态的特性。
  • Datasource会帮我们创建、管理和分配数据库连接,它有多种实现,如:dbcp、Druid、HikariCP等。

接下来看HikariCP是如何获取连接的:通过阅读HikariCP的源码,发现它在初始化的时候最终获取Connection是调用driver.connect(jdbcUrl, driverProperties);,而DriverManager获取Connection也是调用driver.connect(url, info);。具体的连接由数据库的驱动实现。

阅读全文 »

java堆-新生代和老年代

发表于 2017-12-02

java堆是垃圾收集器的主要管理区域,堆可以细分为:新生代和老年代,再细致一点可以分为:Eden区、from survivor区和to survivor区。

堆内存

Java中的堆是JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象。
老年代:新生代=>默认情况下是2:1,可以通过XX:NewRatio=ratio调整比例,默认为2,详细可看官方文档

By default, the Application Server is invoked with the Java HotSpot Server JVM. The default NewRatio for the Server JVM is 2: the old generation occupies 2/3 of the heap while the new generation occupies 1/3. The larger new generation can accommodate many more short-lived objects, decreasing the need for slow major collections. The old generation is still sufficiently large enough to hold many long-lived objects

Eden区:from Survivor区:to Survivor区=>默认情况下是8:1:1,可以通过 -XX:SurvivorRatio=size 来调整比例,默认是8

阅读全文 »

内存分配和回收策略

发表于 2017-11-28

对象的内存分配,往大方向上讲,就是在堆上分配(但也可能经过JIT编译后被拆散为标量类型并间接地在栈上分配),对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配。少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使用的是哪一种垃圾收集器组合,还有虚拟机中与内存相关的参数的设置。

对象优先在Eden区分配

大多数情况下。对象在新生代的Eden区分配。当Eden区没有足够的空间进行分配时,虚拟机将发起一次MinorGC

大对象直接进入老年代

大对象指需要连续大量空间的java对象,如很长的字符串以及数组(byte[10*1024*1024]),虚拟机提供-XX:PretenureSizeThreshold参数,另大于这个设置值的对象直接在老年代分配,避免在Eden区及两个Survivor区之间发生大量的内存复制(新生代:复制算法)。PretenureSizeThreshold只对Serial和ParNew收集器有效,对Parallel Scavenge收集器无效,它一般不需要这个设置。

阅读全文 »

理解GC日志

发表于 2017-11-25

GC日志是一个很重要的工具,它准确记录了每一次的GC的执行时间和执行结果,通过分析GC日志可以优化堆设置和GC设置,或者改进应用程序的对象分配模式。

-XX:+PrintGC

参数-XX:+PrintGC(或者-verbose:gc)开启了简单GC日志模式,为每一次新生代(young generation)的GC和每一次的Full GC打印一行信息。下面举例说明:

1
2
[GC 246656K->243120K(376320K), 0.0929090 secs]
[Full GC 243120K->241951K(629760K), 1.5589690 secs]

每行开始首先是GC的类型(可以是“GC”或者“Full GC”),然后是在GC之前和GC之后已使用的堆空间,再然后是当前的堆容量,最后是GC持续的时间(以秒计)。

-XX:+PrintGCDetails

开启了详细GC日志模式。在这种模式下,日志格式和所使用的GC算法有关。

1
2
3
4
[GC (Metadata GC Threshold) [PSYoungGen: 19427K->4592K(95232K)] 29052K->15061K(129536K), 0.0051148 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
[Full GC (Metadata GC Threshold) [PSYoungGen: 4592K->0K(95232K)] [ParOldGen: 10469K->9121K(34304K)] 15061K->9121K(129536K), [Metaspace: 20783K->20783K(1067008K)], 0.0407688 secs] [Times: user=0.13 sys=0.00, real=0.04 secs]
[GC (Allocation Failure)) [PSYoungGen: 35510K->3651K(92160K)] 44632K->12780K(126464K), 0.0040306 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 3651K->0K(92160K)] [ParOldGen: 9129K->9619K(34304K)] 12780K->9619K(126464K), [Metaspace: 22762K->22762K(1069056K)], 0.0613941 secs] [Times: user=0.27 sys=0.00, real=0.06 secs]

新生代GC

1
[GC (Allocation Failure) [PSYoungGen: 35510K->3651K(92160K)] 44632K->12780K(126464K), 0.0040306 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
  • [GC与[Full GC表示GC类型
  • [PSYoungGen: 35510K->3651K(92160K)] ,其中[PSYoungGen表示GC发生的区域,显示的区域与使用的GC收集器密切相关。这里表示使用了Parallel Scavenge收集器,如果使用Serial收集器,则显示[DefNew,ParNew收集器则为[ParNew。35510K->3651K(92160K)对应:收集前该内存区域(新生代)已使用容量->GC后该内存区域已使用容量(该内存区域总容量)。44632K->12780K(126464K)表示GC前java堆已使用容量->GC后java堆已使用容量(java堆总容量)
  • 0.0040306 secs sec表示该内存区域GC所用时间
  • [Times: user=0.00 sys=0.00, real=0.00 secs]分别代表用户态消耗的CPU时间、内核态消耗的CPU时间和操作从开始到结束所经过的墙钟时间。墙钟时间与CPU时间的区别是墙钟时间包括各种非计算的等待耗时,如磁盘I/O、线程阻塞等待。
    阅读全文 »

java虚拟机垃圾收集器

发表于 2017-11-22

新生代收集器

Serial收集器

采用复制算法,单线程收集器,它进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束,jdk1.3.1之前新生代收集器唯一选择

ParNew收集器

采用复制算法,Serial收集器的多线程版本

Parallel Scavenge收集器

采用复制算法,并行多线程收集器。它的目标则是达到一个可控制的吞吐量。吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),虚拟机运行100分钟,垃圾收集花掉1分钟,着吞吐量就是99%。

阅读全文 »

垃圾收集算法

发表于 2017-11-20

标记-清除算法

如同它的名字一样,分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

缺点
1. 标记和清除两个过程效率不高
2. 标记清除后会产生大量不连续的空间,空间碎片太多导致以后程序分配较大对象时,无法找到足够大的连续空间而不得不提前触发另一次垃圾收集动作
阅读全文 »

java虚拟机运行时数据区域

发表于 2017-11-19

运行时数据区域

java虚拟机所管理的内存将会分为以下几个区域


阅读全文 »

IntelliJ IDEA maven打包报错:Fatal error compiling: 无效的目标发行版: 1.8 -> [Help 1]

发表于 2017-04-20

今天使用IntelliJ IDEA准备对spring-boot开发项目进行打包时,一直报: Fatal error compiling: 无效的目标发行版: 1.8 -> [Help 1] ,但是我的系统环境全部是jdk 1.8,百思不得其解

阅读全文 »

nginx配置静态文件目录404

发表于 2017-01-22

今天使用nginx配置静态文件代理时,访问一直是404,罪魁祸首就是我没搞清楚root与alias的区别。

阅读全文 »
1234…7
Gude

Gude

Stay Hungry. Stay Foolish.

64 日志
27 标签
GitHub
© 2019 Gude   |  Google网站地图   |  百度网站地图   |  Hosted by Coding Pages
由 Hexo 强力驱动
主题 - NexT.Pisces
  |  本站总访问量次   |  您是第 位访客