☆Code Cache滿導(dǎo)致應(yīng)用性能降低

0 問題描述

一個(gè)應(yīng)用在運(yùn)行一段時(shí)間后,隨著訪問量不斷增加灵奖,突然處理能力下降。但是從流量估盘,jstack瓷患,gc上看基本正常。感覺好像突然從 “健康狀態(tài)” 進(jìn)入了 “虛弱狀態(tài)”忿檩。

1 排查問題

  1. 在JVM日志里尉尾,可以發(fā)現(xiàn)如下log:

    Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.
    Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=.
    ...
    “CompilerThread0” java.lang.OutOfMemoryError: requested 2854248 bytes for Chunk::new. Out of swap space?
    

    說明CodeCache已經(jīng)滿了。而且導(dǎo)致這個(gè)時(shí)候JIT就會(huì)停止燥透,JIT一旦停止,就不會(huì)再起來了辨图,可以想象一下班套,如果很多代碼沒有辦法去JIT的話,性能就會(huì)比較差故河。

  2. 使用如下命令檢查一下Code Cache的值:

    jinfo -flag ReservedCodeCacheSize
    

2 解決問題

  1. 一個(gè)可行的方法吱韭,就是擴(kuò)大Code Cache空間:

    使用 -XX:ReservedCodeCacheSize= 指定一個(gè)更大的空間,來支持更多的JIT編譯;

  2. 此外理盆,另一個(gè)可行的方法痘煤,啟用Code Cache的回收機(jī)制:

    通過在啟動(dòng)參數(shù)上增加:-XX:+UseCodeCacheFlushing 來啟用;

    打開這個(gè)選項(xiàng)猿规,在JIT被關(guān)閉之前衷快,也就是CodeCache裝滿之前,會(huì)在JIT關(guān)閉前做一次清理姨俩,刪除一些CodeCache的代碼蘸拔;

    如果清理后還是沒有空間,那么JIT依然會(huì)關(guān)閉环葵。這個(gè)選項(xiàng)默認(rèn)是關(guān)閉的调窍;

3 背景知識(shí)

3.1 JIT即時(shí)編譯

在Java中提到“編譯”,自然很容易想到 javac 編譯器將.java文件編譯成為.class文件的過程张遭,這里的 javac 編譯器稱為前端編譯器邓萨,其他的前端編譯器還有諸如Eclipse,JDT中的增量式編譯器ECJ等菊卷。相對(duì)應(yīng)的還有 后端編譯器缔恳,它在程序運(yùn)行期間將字節(jié)碼轉(zhuǎn)變成機(jī)器碼(現(xiàn)在的Java程序在運(yùn)行時(shí)基本都是 解釋執(zhí)行加編譯執(zhí)行),如HotSpot虛擬機(jī)自帶的JIT(Just In Time Compiler)編譯器(分Client端和Server端)的烁。

Java程序最初是僅僅通過解釋器解釋執(zhí)行的褐耳,即對(duì)字節(jié)碼逐條解釋執(zhí)行,這種方式的執(zhí)行速度相對(duì)會(huì)比較慢渴庆,尤其當(dāng)某個(gè)方法或代碼塊運(yùn)行的特別頻繁時(shí)铃芦,這種方式的執(zhí)行效率就顯得很低。于是后來 在虛擬機(jī)中引入了JIT編譯器(即時(shí)編譯器)襟雷,當(dāng)虛擬機(jī)發(fā)現(xiàn)某個(gè)方法或代碼塊運(yùn)行特別頻繁時(shí)刃滓,達(dá)到某個(gè)閾值,就會(huì)把這些代碼認(rèn)定為“Hot Spot Code”(熱點(diǎn)代碼)耸弄,為了提高熱點(diǎn)代碼的執(zhí)行效率咧虎,在運(yùn)行時(shí),虛擬機(jī)將會(huì)把這些代碼編譯成與本地平臺(tái)相關(guān)的機(jī)器碼计呈,并進(jìn)行各層次的優(yōu)化砰诵,完成這項(xiàng)任務(wù)的正是JIT編譯器。

現(xiàn)在主流的商用虛擬機(jī)(如:Sun HotSpot捌显、IBM J9)中幾乎 都同時(shí)包含解釋器和編譯器茁彭,三大商用虛擬機(jī)之一的JRockit是個(gè)例外,它內(nèi)部沒有解釋器扶歪,因此會(huì)有啟動(dòng)相應(yīng)時(shí)間長(zhǎng)之類的缺點(diǎn)理肺,但它主要是面向服務(wù)端的應(yīng)用,這類應(yīng)用一般不會(huì)重點(diǎn)關(guān)注啟動(dòng)時(shí)間。

解釋器與編輯器二者各有優(yōu)勢(shì):

  1. 當(dāng)程序需要迅速啟動(dòng)和執(zhí)行時(shí)妹萨,解釋器可以首先發(fā)揮作用年枕,省去編譯的時(shí)間,立即執(zhí)行乎完;
  2. 當(dāng)程序運(yùn)行后熏兄,隨著時(shí)間的推移,編譯器逐漸會(huì)發(fā)揮作用囱怕,把越來越多的代碼編譯成本地代碼后霍弹,可以獲取更高的執(zhí)行效率;
  3. 解釋執(zhí)行可以節(jié)約內(nèi)存娃弓,而編譯執(zhí)行可以提升效率典格;

運(yùn)行過程中會(huì)被即時(shí)編譯器編譯的“熱點(diǎn)代碼”有兩類:

  1. 被多次調(diào)用的方法
  2. 被多次調(diào)用的循環(huán)體台丛;

3.2 Code Cache

Java代碼在執(zhí)行時(shí)一旦被編譯器編譯為機(jī)器碼耍缴,下一次執(zhí)行的時(shí)候就會(huì)直接執(zhí)行編譯后的代碼,也就是說挽霉,編譯后的代碼被緩存了起來防嗡。緩存編譯后的機(jī)器碼的內(nèi)存區(qū)域就是codeCache。這是一塊獨(dú)立于Java堆之外的內(nèi)存區(qū)域侠坎。除了JIT編譯的代碼之外蚁趁,Java所使用的本地方法代碼(JNI)也會(huì)存在codeCache中

JVM運(yùn)行時(shí)內(nèi)存區(qū)域实胸,堆與非堆劃分

Code Cache是JVM用于存儲(chǔ)經(jīng)過JIT C1/C2編譯優(yōu)化后的代碼他嫡。因?yàn)槭谴嬖趦?nèi)存中的,所以肯定得限制大小庐完,Code Cache的最大大小可通過jinfo -flag ReservedCodeCacheSize來獲取钢属,通常在64 bit機(jī)器上默認(rèn)是48m

不同版本的JVM门躯、不同的啟動(dòng)方式codeCache的默認(rèn)大小也不同:

JVM 版本和啟動(dòng)方式 默認(rèn) codeCache大小
32-bit client, Java 8 32 MB
32-bit server, Java 8 48M
32-bit server with Tiered Compilation, Java 8 240 MB
64-bit server, Java 8 48M
64-bit server with Tiered Compilation, Java 8 240 MB
32-bit client, Java 7 32 MB
32-bit server, Java 7 48 MB
32-bit server with Tiered Compilation, Java 7 96 MB
64-bit server, Java 7 48 MB
64-bit server with Tiered Compilation, Java 7 96 MB

3.3 分層編譯

JVM提供了一個(gè)參數(shù)-Xcomp淆党,可以使JVM運(yùn)行在純編譯模式下,所有方法在第一次被調(diào)用的時(shí)候就會(huì)被編譯成機(jī)器代碼讶凉。加上這個(gè)參數(shù)之后染乌,隨之而來的問題是啟動(dòng)時(shí)間變得很長(zhǎng),差不多是原來的2倍還多懂讯。

除了純編譯方式和默認(rèn)的mixed之外慕匠,從JDK6u25開始引入了一種分層編譯的方式

Hotspot JVM內(nèi)置了2種編譯器域醇,分別是 client方式啟動(dòng)時(shí)用的C1編譯器server方式啟動(dòng)時(shí)用的C2編譯器

  1. C2編譯器在將代碼編譯成機(jī)器碼之前,需要收集大量的統(tǒng)計(jì)信息以便在編譯的時(shí)候做優(yōu)化譬挚,因此編譯后的代碼執(zhí)行效率也高锅铅,代價(jià)是程序啟動(dòng)速度慢,并且需要比較長(zhǎng)的執(zhí)行時(shí)間才能達(dá)到最高性能减宣;

  2. C1編譯器的目標(biāo)在于使程序盡快進(jìn)入編譯執(zhí)行階段盐须,因此編譯前需要收集的統(tǒng)計(jì)信息比C2少很多,編譯速度也快不少漆腌。代價(jià)是編譯出的目標(biāo)代碼比C2編譯的執(zhí)行效率要低贼邓。

盡管如此,C1編譯的執(zhí)行效率也比解釋執(zhí)行有巨大的優(yōu)勢(shì)闷尿。分層編譯方式是一種折衷方式塑径,在系統(tǒng)啟動(dòng)之初執(zhí)行頻率比較高的代碼將先被C1編譯器編譯,以便盡快進(jìn)入編譯執(zhí)行填具。隨著時(shí)間推進(jìn)统舀,一些執(zhí)行頻率高的代碼會(huì)被C2編譯器再次編譯,從而達(dá)到更高的性能劳景。

通過以下JVM參數(shù)開啟分層編譯模式:

-XX:+TieredCompilation 

在JDK8中誉简,當(dāng)以server模式啟動(dòng)時(shí),分層編譯默認(rèn)開啟盟广。需要注意的是闷串,分層編譯方式只能用于server模式中,如果需要關(guān)閉分層編譯筋量,需要加上啟動(dòng)參數(shù) -XX:-TieredCompilation烹吵;如果以client模式啟動(dòng),-XX:+TieredCompilation 參數(shù)將會(huì)被忽略毛甲。

3.4 Code Cache 滿了怎么辦

隨著時(shí)間推移年叮,會(huì)有越來越多的方法被編譯,codeCache使用量會(huì)逐漸增加玻募,直至耗盡只损。當(dāng)Code Cache用滿了后,會(huì)打印下面的日志:

在JDK1.7.0_4之前七咧,你會(huì)在jvm的日志里看到這樣的輸出:

Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.
Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=.
...
“CompilerThread0” java.lang.OutOfMemoryError: requested 2854248 bytes for Chunk::new. Out of swap space?
  1. JIT編譯器被停止了跃惫,并且不會(huì)被重新啟動(dòng),此時(shí)會(huì)回歸到解釋執(zhí)行艾栋;

  2. 被編譯過的代碼仍然以編譯方式執(zhí)行爆存,但是尚未被編譯的代碼就 只能以解釋方式執(zhí)行了

針對(duì)這種情況蝗砾,JVM提供了一種比較激進(jìn)的codeCache回收方式:Speculative flushing先较。

在JDK1.7.0_4之后這種回收方式默認(rèn)開啟携冤,而之前的版本需要通過一個(gè)啟動(dòng)參數(shù)來開啟:-XX:+UseCodeCacheFlushing

在Speculative flushing開啟的情況下闲勺,當(dāng)codeCache將要耗盡時(shí):

  1. 最早被編譯的一半方法將會(huì)被放到一個(gè)old列表中等待回收曾棕;

  2. 在一定時(shí)間間隔內(nèi),如果old列表中方法沒有被調(diào)用菜循,這個(gè)方法就會(huì)被從codeCache充清除翘地;

很不幸的是,在JDK1.7中癌幕,當(dāng)codeCache耗盡時(shí)衙耕,Speculative flushing釋放了一部分空間,但是從編譯日志來看勺远,JIT編譯并沒有恢復(fù)正常橙喘,并且系統(tǒng)整體性能下降很多,出現(xiàn)大量超時(shí)谚中。

在Oracle官網(wǎng)上看到這樣一個(gè)Bug:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8006952 由于codeCache回收算法的問題渴杆,當(dāng)codeCache滿了之后會(huì)導(dǎo)致編譯線程無法繼續(xù),并且消耗大量CPU導(dǎo)致系統(tǒng)運(yùn)行變慢宪塔。Bug里影響版本是JDK8磁奖,但是從網(wǎng)上其他地方的信息看,JDK7應(yīng)該也存在相同的問題某筐,并且沒有被修復(fù)比搭。

所以,目前來看南誊,開啟UseCodeCacheFlushing會(huì)導(dǎo)致問題身诺,如下

  1. Code Cache滿了時(shí)緊急進(jìn)行清掃工作,它會(huì)丟棄一半老的編譯代碼抄囚;
  2. Code Cache空間降了一半霉赡,方法編譯工作仍然可能不會(huì)重啟
  3. flushing可能導(dǎo)致高的cpu使用幔托,從而影響性能下降穴亏;

3.6 Code Cache 調(diào)優(yōu)

以client模式或者是分層編譯模式運(yùn)行的應(yīng)用,由于需要編譯的類更多(C1編譯器編譯閾值低重挑,更容易達(dá)到編譯標(biāo)準(zhǔn))嗓化,所以更容易耗盡codeCache。當(dāng)發(fā)現(xiàn)codeCache有不夠用的跡象(通過上一節(jié)提到的監(jiān)控方式)時(shí)谬哀,可以通過啟動(dòng)參數(shù)來調(diào)整codeCache的大小刺覆。

-XX:ReservedCodeCacheSize=256M

那具體應(yīng)該設(shè)置為多大合適,根據(jù)監(jiān)控?cái)?shù)據(jù)估算史煎,例如單位時(shí)間增長(zhǎng)量谦屑、系統(tǒng)最長(zhǎng)連續(xù)運(yùn)行時(shí)間等驳糯。如果沒有相關(guān)統(tǒng)計(jì)數(shù)據(jù),一種推薦的設(shè)置思路是設(shè)置為當(dāng)前值(或者默認(rèn)值)的2倍伦仍。

需要注意的是结窘,這個(gè)codeCache的值不是越大越好對(duì)于32位JVM充蓝,能夠使用的最大內(nèi)存空間為4g。這個(gè)4g的內(nèi)存空間不僅包括了java堆內(nèi)存喉磁,還包括JVM本身占用的內(nèi)存谓苟、程序中使用的native內(nèi)存(比如directBuffer)以及codeCache。如果將codeCache設(shè)置的過大协怒,即使沒有用到那么多涝焙,JVM也會(huì)為其保留這些內(nèi)存空間,導(dǎo)致應(yīng)用本身可以使用的內(nèi)存減少孕暇。對(duì)于64位JVM仑撞,由于內(nèi)存空間足夠大,codeCache設(shè)置的過大不會(huì)對(duì)應(yīng)用產(chǎn)生明顯影響妖滔。

在JDK 8中隧哮,提供了一個(gè)啟動(dòng)參數(shù) -XX:+PrintCodeCache 在JVM停止的時(shí)候打印出codeCache的使用情況。其中max_used就是在整個(gè)運(yùn)行過程中codeCache的最大使用量座舍【谙瑁可以通過這個(gè)值來設(shè)置一個(gè)合理的codeCache大小,在保證應(yīng)用正常運(yùn)行的情況下減少內(nèi)存使用曲秉。

3.7 問題解決

問題的前因后果都弄清楚了采蚀,也就好解決了。上面提到過純編譯方式和分層編譯方式都可以解決或緩解啟動(dòng)后負(fù)載過高的問題承二,那么我們就有2種選擇:

  1. 采用分層編譯方式榆鼠,并修改codeCache的大小為256M;

  2. 采用純編譯方式亥鸠,并修改codeCache的大小為256M妆够;

經(jīng)過一段時(shí)間運(yùn)行發(fā)現(xiàn),在啟動(dòng)后負(fù)載控制方面读虏,純編譯方式要好一些责静,啟動(dòng)之后負(fù)載幾乎不上升,而 分層編譯方式啟動(dòng)后負(fù)載會(huì)有所上升盖桥,但是不會(huì)很高灾螃,也會(huì)在較短時(shí)間內(nèi)降下來。但是啟動(dòng)時(shí)間方面揩徊,分層編譯比原來的默認(rèn)啟動(dòng)方式縮短了大概10秒(原來啟動(dòng)需要110-130秒)腰鬼,而純編譯方式啟動(dòng)時(shí)間比原來多了一倍嵌赠,達(dá)到了250秒甚至更高。所以看起來分層編譯方式是更好的選擇熄赡。

然而JDK 7在codeCache的回收方面做的很不好姜挺。即使我們將codeCache設(shè)置為256M,線上還是輕易達(dá)到了設(shè)置的報(bào)警閾值200M彼硫。而且一旦codeCache滿了之后又會(huì)導(dǎo)致系統(tǒng)運(yùn)行變慢的問題炊豪。所以我們的目標(biāo)指向了JDK 8

測(cè)試表明拧篮,JDK 8對(duì)codeCache的回收有了很明顯的改善词渤。不僅codeCache的增長(zhǎng)比較平緩,而且當(dāng)使用量達(dá)到75%時(shí)串绩,回收力度明顯加大缺虐,codeCache使用量在這個(gè)值上下浮動(dòng),并緩慢增長(zhǎng)礁凡。最重要的是高氮,JIT編譯還在正常執(zhí)行,系統(tǒng)運(yùn)行速度也沒有收到影響顷牌。

3.8 運(yùn)行時(shí)查看Code Cache

如果想在運(yùn)行時(shí)查看code cache的大小剪芍,需要寫段代碼,目前只能通過JMX來獲取到Code Cache區(qū)域的使用狀況韧掩,代碼類似如下:

import java.io.File;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import com.sun.tools.attach.VirtualMachine;

public class CodeCacheUsage {

    private static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress";

    public static void main(String[] args) throws Exception {
        if(args.length != 1) {
            System.err.println("Must enter one arg: pid");
            System.exit(0);
        }
        VirtualMachine vm = VirtualMachine.attach(args[0]);
        JMXConnector connector = null;
        try {
            String connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);

            if (connectorAddress == null) {
                String agent = vm.getSystemProperties().getProperty("java.home")
                                        + File.separator
                                        + "lib"
                                        + File.separator + "management-agent.jar";
                vm.loadAgent(agent);

                connectorAddress = vm.getAgentProperties().getProperty(CONNECTOR_ADDRESS);
            }

            JMXServiceURL url = new JMXServiceURL(connectorAddress);
            connector = JMXConnectorFactory.connect(url);
            MBeanServerConnection mbeanConn = connector.getMBeanServerConnection();
            ObjectName name = new ObjectName("java.lang:type=MemoryPool,name=Code Cache");
            System.out.println(mbeanConn.getAttribute(name, "Usage"));
        } finally {
            if(connector != null)
                connector.close();
            vm.detach();
        }
    }
}

傳入pid紊浩,執(zhí)行上面的代碼后,會(huì)輸出類似下面的信息:

javax.management.openmbean.CompositeDataSupport(compositeType=javax.management.openmbean.CompositeType(name=java.lang.management.MemoryUsage,items=
(
(itemName=committed,itemType=javax.management.openmbean.SimpleType(name=java.lang.Long)),
(itemName=init,itemType=javax.management.openmbean.SimpleType(name=java.lang.Long)),
(itemName=max,itemType=javax.management.openmbean.SimpleType(name=java.lang.Long)),
(itemName=used,itemType=javax.management.openmbean.SimpleType(name=java.lang.Long))
)),
contents={committed=50331648, init=2555904, max=50331648, used=48281152})

上面的信息顯示Code Cache區(qū)域初始化的時(shí)候?yàn)?555904疗锐,最大為50331648坊谁,已占用了50331648,使用了48281152滑臊。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末口芍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子雇卷,更是在濱河造成了極大的恐慌鬓椭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件关划,死亡現(xiàn)場(chǎng)離奇詭異小染,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)贮折,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門裤翩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人调榄,你說我怎么就攤上這事踊赠『强福” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵筐带,是天一觀的道長(zhǎng)今穿。 經(jīng)常有香客問我,道長(zhǎng)伦籍,這世上最難降的妖魔是什么蓝晒? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮鸽斟,結(jié)果婚禮上拔创,老公的妹妹穿的比我還像新娘。我一直安慰自己富蓄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布慢逾。 她就那樣靜靜地躺著立倍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侣滩。 梳的紋絲不亂的頭發(fā)上口注,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音君珠,去河邊找鬼寝志。 笑死,一個(gè)胖子當(dāng)著我的面吹牛策添,可吹牛的內(nèi)容都是我干的材部。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼唯竹,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼乐导!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起浸颓,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤物臂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后产上,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棵磷,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年晋涣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仪媒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡姻僧,死狀恐怖规丽,靈堂內(nèi)的尸體忽然破棺而出蒲牧,到底是詐尸還是另有隱情,我是刑警寧澤赌莺,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布冰抢,位于F島的核電站,受9級(jí)特大地震影響艘狭,放射性物質(zhì)發(fā)生泄漏挎扰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一巢音、第九天 我趴在偏房一處隱蔽的房頂上張望遵倦。 院中可真熱鬧,春花似錦官撼、人聲如沸梧躺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掠哥。三九已至,卻和暖如春秃诵,著一層夾襖步出監(jiān)牢的瞬間续搀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工菠净, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留禁舷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓毅往,卻偏偏與公主長(zhǎng)得像牵咙,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子煞抬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 有業(yè)務(wù)反饋革答,線上一個(gè)應(yīng)用運(yùn)行了一段時(shí)間之后战坤,在高峰期之后,突然發(fā)現(xiàn)處理能力下降残拐,接口的響應(yīng)時(shí)間變長(zhǎng)途茫,但是看Cat上...
    美團(tuán)Java閱讀 5,900評(píng)論 6 39
  • JITJIT C1Client模式啟動(dòng)速度較快桌面應(yīng)用,加載速度比server模式快10%溪食,而運(yùn)行速度為serve...
    andersonoy閱讀 5,695評(píng)論 2 4
  • JVM對(duì)代碼執(zhí)行的優(yōu)化可分為運(yùn)行時(shí)(runtime)優(yōu)化和即時(shí)編譯器(JIT)優(yōu)化囊卜。運(yùn)行時(shí)優(yōu)化主要是解釋執(zhí)行和動(dòng)態(tài)...
    全菜工程師小輝閱讀 3,937評(píng)論 0 1
  • JVM性能調(diào)優(yōu) 1 堆設(shè)置調(diào)優(yōu) 年輕代大小選擇 響應(yīng)時(shí)間優(yōu)先的應(yīng)用:盡可能設(shè)大,直到接近系統(tǒng)的最低響應(yīng)時(shí)間限制(根...
    高廣超閱讀 4,206評(píng)論 0 21
  • 四個(gè)人,像四顆星栅组,又像是四枚棋子雀瓢,兩兩對(duì)坐。 四個(gè)人吃火鍋玉掸,三種口味的鍋底刃麸。一份番茄味的。一份養(yǎng)生菌...
    左岸梅花閱讀 234評(píng)論 0 2