![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
JVM
__KevinYzy__
github:https://github.com/KEVINYZY ----
leetcode:https://leetcode.com/seanadfgfeer/ ----
lintcode:https://www.lintcode.com/user/fire-blade ----
nowcoder:https://www.nowcoder.com/profile/1073818
展开
-
GC算法基础
GC算法:基础篇在深入GC算法的实现细节之前,我们最好先来了解下相关术语及背后的基本原理。不同回收器的实现细节各有不同,但总的来说基本所有的回收器都会关注如下两个方面:找出所有的存活对象清理掉所有的其它对象——也就是那些被认为是废弃或无用的对象。首先,所有回收器都会通过一个标记过程来对存活对象进行统计。标记可达对象JVM中用到的所有现代GC算法在回收前都会先找出所有仍存活的对象。下图中...原创 2020-04-27 10:14:46 · 122 阅读 · 0 评论 -
Java中的垃圾回收
前文中对标记删除算法的介绍更多还是偏理论性质的。实践中,为了更好地满足现实的场景及需求,还需要对算法进行大量的调整。举个简单的例子,我们来看下JVM需要记录哪些信息才能让我们得以安全地分配对象空间。碎片及整理(Fragmenting and Compacting)JVM在清除不可达对象之后,还得确保它们所在的空间是可以进行复用的。对象删除会导致碎片的出现,这有点类似于磁盘碎片,这会带来两个问题...原创 2020-04-27 10:15:40 · 141 阅读 · 0 评论 -
弱引用,软引用及虚引用对GC的影响
在应用程序中使用非强引用会导致一系列的问题,对GC的响应时间及吞吐量都会有所影响。尽管这类引用在某些场景下可以减少OutOfMemoryError的出现频率,但过度的使用则会严重影响到垃圾回收,从而导致应用程序的性能遭受影响。应该注意什么?在使用弱引用时,你最好了解一下它是如何被回收的。一旦垃圾回收器发现有一个对象是弱可达的,也就是说,它只剩下弱引用了,这个对象就会被放到一个相应的Refere...原创 2020-04-27 10:16:09 · 791 阅读 · 0 评论 -
什么是垃圾回收
本文摘自我们几周后即将出版的Garbage Collection Handbook一书的样章。同时也让你能熟悉下垃圾回收的基础知识——这选自该书的第一章。乍一看,垃圾回收所做的事情应当恰如其名——查找并清除垃圾。事实上却恰恰相反。垃圾回收会跟踪所有仍在使用的对象,然后将剩余的对象标记为垃圾。牢记了这点之后,我们再来深入地了解下这个被称为“垃圾回收”的自动化内存回收在JVM中到底是如何实现的。手...原创 2020-04-27 10:18:20 · 116 阅读 · 0 评论 -
Full GC是否真的存在
在Plumbr这和GC暂停检测打交道的这段日子里,我查阅了与这个主题相关的大量文章,书籍以及资料。在这当中,我经常会对新生代GC, 年老代GC以及Full GC的事件的使用(滥用)感到困惑。于是便有了这篇文章,希望能够清除一些困惑。本文需要读者对JVM内建的GC相关的常用原理有一定的了解。像eden区,Survivor区以及年老区空间的划分,分代假设(generational hypothesi...原创 2020-04-27 10:18:34 · 146 阅读 · 0 评论 -
JVM堆大小的自适应能力
在完善我们的测试台以便提高Plumbr排查GC故障能力的时候,我编写了一个小小的测试用例,我觉得应该会有不少人对它感兴趣。我的目标是测试JVM在不同的伊甸区(Eden), 存活区(Survivor)以及年老代空间的分配情况下的自适应能力。这个测试用例就是在批量地生成对象。每秒会批量生成一批,每批大概是500KB的大小。这些对象的生命周期是5秒钟,之后它们的引用会被删除掉,然后就可以进行垃圾回收了...原创 2020-04-27 10:19:38 · 533 阅读 · 0 评论 -
Java 8的元空间
本文我们将会介绍JVM的一个更新,这就是持久代的移除。我们会介绍为什么需要移除持久代,以及它的替代者,元空间(metaspace)。这是上一篇文章内存管理之垃圾回收的续集。Java 6中的堆结构是这样的:持久代持久代中包含了虚拟机中所有可通过反射获取到的数据,比如Class和Method对象。不同的Java虚拟机之间可能会进行类共享,因此持久代又分为只读区和读写区。JVM用于描述应用程序中...原创 2020-04-27 10:20:35 · 168 阅读 · 0 评论 -
Java的Finalizer引发的内存溢出
本文介绍的是Java里一个内建的概念,Finalizer。你可能对它对数家珍,但也可能从未听闻过,这得看你有没有花时间完整地看过一遍java.lang.Object类了。在java.lang.Object里面就有一个finalize()的方法。这个方法的实现是空的,不过一旦实现了这个方法,就会触发JVM的内部行为,威力和危险并存。如果JVM发现某个类实现了finalize()方法的话,那么见证奇...原创 2020-04-27 10:21:52 · 521 阅读 · 0 评论 -
Java的内存泄露
Java有垃圾回收,因此不会出现内存泄露。 大错特错。这个说法存在好几个问题。尽管Java的确有垃圾回收器来回收那些不用的内存块,但你不要指望它能够点铁成金。GC减轻了开发人员肩上的负担,而原本的那些工作非常容易出错,不过并不是所有内存分配的问题它都能够解决。更糟糕的是,Java的设计允许它可以欺骗GC,使得它能够保留一些程序已经不再使用的内存。经历了20年的C开发以及7年的Java开发后(中间...原创 2020-04-27 10:28:42 · 109 阅读 · 0 评论 -
G1,CMS及PARALLEL GC的比较
这篇文章正好接上前一年我们做的一次现实环境下不同GC算法性能比较的试验。这次我们仍然进行同样的试验,不过增加了对G1回收器的测试,并且在多个平台进行测试。今年我们测试的垃圾回收器有如下几个:-XX:+UseParallelOldGC-XX:+UseConcMarkSweepGC-XX:+UseG1GC运行环境我们使用现成的JIRA任务来运行这个测试。选择它的原因非常简单——除去Minec...原创 2020-04-27 10:28:29 · 4621 阅读 · 1 评论 -
关于类加载器内存泄露的分析
从上个世纪90年代Java诞生之日起,Java的类和资源的加载就一直是个问题。由于它增加了启动和初始化时间,因此这个问题在Java应用服务器上则尤为明显。为了缓解这个问题,大家试过了不同的访问,比如说以exploaded方式部署,但这只对简单的应用有效;还有2001年发明的Java热插拔的机制。启用热插拔的话,你在一个现有的方法内的改动马上就会生效。由于方法的边界限制,这个方法并不是特别有用,通常...原创 2020-04-27 10:28:12 · 376 阅读 · 0 评论 -
Twitter:使用Netty 4来减少GC开销
在twitter,需要网络功能的核心模块使用的都是Netty。 比方说:Finagle是我们的协议无关的RPC系统,它的传输层是在Netty之上构建的,许多内部的服务都是通过它来实现的,比如说搜索服务。TFE(Twitter Front End,Twitter前端)是我们专门的填鸭式反向代理,它使用Netty支撑了大部分面向公众的HTTP及SPDY的流量。Cloudhopper每个月都通过N...原创 2020-04-27 10:27:20 · 241 阅读 · 0 评论 -
浅谈GC调优
复杂的东西我们可不喜欢。一直以来,内存泄露,线程锁,GC调优这些东西处理起来都很痛苦。这三个邪恶的小伙伴带来的性能问题是最难复现的,这也使得修复这些问题有如噩梦一般。如果你不信的话,看一下LinkedIn最近关于性能调优的一篇文章就知道了。尽管这篇文章很好的剖析了性能调优的过程,但它也很好的证明了这个领域的复杂性。LinkedIn的工程师进行GC调优改善吞吐量和延迟用的是下面这组参数:-ser...原创 2020-04-27 10:27:04 · 151 阅读 · 0 评论 -
HotSpot JVM就是个庞氏骗局
正好今天是愚人节,就来说点骗子的东西吧~时不时的我就会听见有人抱怨说,他的HotSpot JVM不停的在垃圾回收,可是每次回收完后堆却还是满的。当他们发现这是因为JVM的内存已经不够了之后,通常会问这么个问题,为什么JVM不抛一个OutOfMemoryError(OOME)呢?毕竟来说,由于内存不足,我的程序都已经没法继续跑了,对吧?先说重要的,如果你运气好的话,你永远不会发现你的JVM其实在...原创 2020-04-27 10:24:39 · 221 阅读 · 0 评论 -
自己动手写GC
有时候事情多得我喘不过气来的时候,我会出现一种异常反应,好像找点别的事做,就能摆脱烦恼了。通常的话我会自己写一些独立的小程序。有一天早上,我正在写的书,工作中的事情,还有要为Strang Loop准备的分享,这些东西让我感到快崩溃了,突然间我想到,“我要写一个垃圾回收程序”。是的,我知道这听起来有点疯狂。不过你可以把我这个荒唐的想法当成是一份编程语言基础的免费教程。通过百来行普通的C代码,我实...原创 2020-04-27 10:23:27 · 4088 阅读 · 0 评论 -
关于Java中尾递归的优化
最近总有人问我,Java SE8里有没有针对尾调用做优化(这是一种特殊的函数调用)。这个优化和递归调用密切相关,而递归调用对函数式语言来说尤其重要,因为它们通常都基于递归来进行设计编码。本文会介绍到什么是尾调用,怎样可以对它进行有效的优化,以及Java 8在这方面是如何做的。在深入这个话题之前,我们先来了解下什么是尾调用。什么是尾调用?尾调用指的是一个方法或者函数的调用在另一个方法或者函数的...原创 2020-04-27 10:35:28 · 455 阅读 · 0 评论 -
不容忽视的ClassNotFoundException
相信很多Java开发人员都对这个常见却不招人待见的java.lang.ClassNotFoundException并不陌生。出现这个异常的原因大家都清楚(classpath路径下缺少class文件或者jar包了,或者是类加载器委派的问题等),不过对于它给JVM带来的性能影响可能就不了解了。这个异常可能会严重影响应用程序的响应时间和可伸缩性。大型的J2EE企业级应用,可能会同时部署有多个应用,由于...原创 2020-04-27 10:35:13 · 454 阅读 · 0 评论 -
Java字节码运行浅析
明白Java代码是如何编译成字节码并在JVM上运行的非常重要,这有助于理解程序运行的时候到底发生了些什么。理解这点不仅能搞清语言特性是如何实现的,并且在做方案讨论的时候能知道相应的副作用及权衡利弊。本文介绍了Java代码是如何编译成字节码并在JVM上执行的。想了解JVM的内部结构以及字节码运行时用到的各个内存区域,可以看下我前面的一篇关于JVM内部细节的文章。本文分为三部分,每一部分都分成几个...原创 2020-04-27 10:55:50 · 135 阅读 · 0 评论 -
JVM的几点性能优化
HotSpot,家喻户晓的JVM,我们的Java和Scala程序就运行在它上面。年复一年,一次又一次的迭代,经过无数工程师的不断优化,现在它的代码执行的速度和效率已经逼近本地编译的代码了。它的核心是一个JIT(Just-In-Time)编译器。JIT只有一个目的,就是为了提升你代码的执行速度,这也是HotSpot能如此流行和成功的重要因素。JIT编译器都做了什么?你的代码在执行的时候,JVM...原创 2020-04-27 10:34:54 · 134 阅读 · 0 评论 -
通过反射跟踪JVM的运行时状态
我们经常会在工作中用到反射,要么直接使用,要么通过一些框架。在Java和Scala编程里,如果想要和我们的代码进行跟踪交互,却又希望对代码透明,最主流的一个方式就是反射。不过我们用到的反射通常都局限在Java和Scala代码里,并运行在JVM中。如果我们不仅是要跟踪自己的代码,还想跟踪JVM的代码怎么办呢?当我们开始构建 Takipi站点的时候,我们想寻找一种能有效跟踪JVM堆内存的方式,以便进...原创 2020-04-27 10:34:39 · 141 阅读 · 0 评论 -
JVM之动态方法调用:invokedynamic
在本文的前面的姊妹篇中,介绍了Java方法调用的5种操作码中的4种。它们是Java 8和Java 9中方法调用的标准字节码形式。于是第五个操作码invokedynamic便进入了我们的视线。简单来说,Java 7中在语言层面上对invokedynamic是没有直接支持的。事实上,当Java 7的运行时首次引入invokedynamic指令时,javac编译器是不会生成这个字节码的。而到了Jav...原创 2020-04-27 10:33:46 · 363 阅读 · 0 评论 -
JVM中方法调用的实现机制
本文将要介绍一下Java 8和Java 9中JVM是如何进行方法调用的。这是JVM内部实现的基础机制,如果你想理解JVM的just-in-time(JIT)编译器或者进行应用程序调优的话,这些是必需的背景知识。字节码分析我们先从一段简单的Java代码开始:long time = System.currentTimeMillis();HashMap<String, String>...原创 2020-04-27 10:33:12 · 688 阅读 · 0 评论 -
JVM优化之逃逸分析与分配消除
在Java Magazine的前几期文章中,我们介绍了just-in- time (JIT) 编译技术的一些理论基础,以及如何使用Java Microbenching Harness(JMH)和开源工具JITWatch来进行可视化分析,以便搞清楚HotSpot VM的内部机制。在这期文章中,我们将要深入介绍一下逃逸分析(escape analysis)技术,这是JVM最有意思的优化手段之一。逃逸分...原创 2020-04-27 10:32:40 · 167 阅读 · 0 评论 -
JVM优化之逃逸分析及锁消除
逃逸分析——我们在上一篇文章中所介绍的由编译器完成的一项的分析技术——使得删除锁的优化成为了可能。如果它能确认某个加锁的对象不会逃逸出局部作用域,就可以进行锁删除。这意味着这个对象同时只可能被一个线程访问,因此也就没有必要防止其它线程对它进行访问了。这样的话这个锁就是可以删除的。这个便叫做锁消除,本文是JVM实现机制的系列文章,这也正是今天要讲的主题。众所周知,java.lang.StringB...原创 2020-04-27 10:32:07 · 220 阅读 · 0 评论 -
JVM优化之循环展开(附有详细的汇编代码)
在JVM内部实现系列的前几篇文章中,我们已经看到了Java的HotSpot虚拟机的just-in-time (JIT)编译技术,包括逃逸分析和锁消除。本文我们将要讨论另一种自动优化,叫作循环展开。JIT编译器使用这项技术来让循环(比如Java的for或者while循环)执行得更加高效。由于我们要对JVM的内部机制进行深入分析,所以你会时不时看到用于讲解介绍的各种C的代码甚至是汇编语言,扶稳了!...原创 2020-04-27 10:31:29 · 878 阅读 · 0 评论 -
通过JVM日志来进行安全点分析
许多事件都可能会导致JVM暂停所有的应用线程。这类暂停又被称为"stop-the-world"(STW)暂停。触发STW暂停最常见的原因就是垃圾回收了(github中的一个例子),但不同的JIT优化(例子),偏向锁擦除(例子),特定的JVMTI操作,以及许多场景都可能会导致应用程序暂停。应用程序线程可以被安全地停止掉的那个时间点,就叫做安全点。这一术语也通常用来指代SWT暂停。通常来讲GC日志...原创 2020-04-27 10:31:05 · 495 阅读 · 0 评论 -
类加载与锁
本文写作的灵感来自Pierre-Hugues Charbonneau的为什么加载不存在的类会影响系统性能一文。这让我想起了之前的一次调试经历,当时也遇到了类似的问题,只不过表现略有不同。出问题的应用程序是Yet Another Webapp,不管什么脏活累活它都接。直到干趴下为止。它这的症状是,终端用户抱怨说应用很慢,经常超时。我从日志文件中倒没发现什么异常,不过能够看出用户体验确实是下降得很厉...原创 2020-04-27 10:30:37 · 204 阅读 · 0 评论 -
遗失的JVM堆内存
“HI,你能不能过来帮我看下这个奇怪的现象?”我之所以会写这篇文章是因为我在一个技术支持的案例中遇到了这么一个情况。这个问题是由于不同的JVM工具所检测出来的可用内存的大小不一致所产生的。简言之,就是有一个工程师在排查某个应用内存使用过多的问题,而他一直“认为”这个程序的堆是2G的。由于某些原因,JVM工具貌似也不太确定这个进程的堆到底有多大。比如说,jconsole认为这个堆的最大可用内存为1...原创 2020-04-27 10:40:41 · 104 阅读 · 0 评论 -
JVMTI的对象标记对GC的影响
本文主要是想分析下为什么Plumbr代理在特定的场景下会对GC的暂停时间产生影响,以及影响究竟有多大。在排查这个故障的过程中,我们还发现,在GC暂停的时候,JVMTI(JVM Tool Interface)的打标记操作存在一些有趣的现象。问题定位我们的一位客户抱怨说当他们的应用程序连接上我们的Plumbr代理之后响应速度会明显变慢。在检查了GC日志之后,我们发现GC的时间存在异常。下面是没有使...原创 2020-04-27 10:41:07 · 154 阅读 · 0 评论 -
JVM:32G以上的堆会发生什么
这篇短文主要是想告诉你如果给Oracle JVM配置超过32G的堆会发生什么事情。默认情况下,堆大小在32G以下的话JVM中的引用会占用4个字节。这是JVM在启动的时候就已经决定了的。如果你去掉了-XX:-UseCompressedOops选项的话,当然也可以在较小的堆上使用8字节的引用(但在生产系统中这么做是毫无意义的!)。一旦堆超过了32G,你就进入到64位的世界里了,因此对象引用就只能是8...原创 2020-04-27 10:41:35 · 582 阅读 · 0 评论 -
GraalVM:在容器内部署Java本地镜像
GraalVM是一款可以运行不同语言程序的高性能虚拟机。目前它能运行包括Java, Scala, Kotlin以及Groovy在内的JVM语言。它还支持JavaScript,Node.js, Ruby, R, Python以及LLVM能支持的原生语言。GraalVM有许多用途,对于云部署及容器领域,其中的一项特性可能最让人兴奋不已。它可以将JVM字节码提前编译成本地可执行文件或共享库,而生成的二进...原创 2020-04-27 10:41:52 · 1254 阅读 · 0 评论 -
下一代JVM:GraalVM的十大特性
GraalVM有许多不同的组件,如果你只是听说过它或有些简单的了解,肯定无法一窥全豹。本文将列举下GraalVM的几大常用功能,看看它们都能做些什么。高性能的现代Java占用资源少,启动速度快JavaScript, Java, Ruby以及R混合编程在JVM上运行原生语言跨语言工具JVM应用扩展原生应用扩展本地Java库数据库支持多语言创建自己的语言本文将要介绍的内容在Gra...原创 2020-04-27 10:42:06 · 3552 阅读 · 0 评论 -
下一代的多语言JVM:GraalVM
GraalVM是一款高性能的可嵌入式多语言虚拟机,它能运行不同的编程语言,包括:基于JVM的语言,比如Java, Scala, Kotlin和Groovy解释型语言,比如JavaScript, Ruby, R和Python配合LLVM一起工作的原生语言,比如C, C++, Rust和SwiftGraalVM能有效地支持多语言应用,你可以在一个进程里同时使用多种编程语言而不会带来明显的性能开...原创 2020-04-27 10:42:19 · 194 阅读 · 0 评论 -
Java 10的类型推导
Java 10带来了全新的语言特性:局部变量类型推导(local variable type inference)。它的主要目标就是减少样板代码(boilerplate),增强代码可读性。可以使用关键词var来替代局部变量的类型声明——编译器会根据变量初始化语句来自己填充正确的类型的。比如说:Map<User, List> userChannels = new HashMap<...原创 2020-04-27 10:42:38 · 207 阅读 · 0 评论