沉淀、分享、成長,讓自己和他人都能有所收獲!😄
看了一篇文章30歲有多難!
每篇文章的開篇總喜歡寫一些,從個人視角看這個世界的感悟。
最近看到一篇文章,30歲有多難
。文中的一些主人公好像在學業(yè)、工作、生活、愛情等方面都過的都不如意。要不是錯過這,要不是走錯那??偨Y來看,就像是很倒霉的一群倒霉蛋兒在跟生活對干!
但其實每個人可能都遇到過生活中最難的時候,或早或晚。就像我剛畢業(yè)不久時一連串遇到;冬天里丟過第一部手機
、修一個進了水的電腦
、租的房子第一次被騙
,一連串下來頭一次要趕在工資沒發(fā)的時候,選擇少吃早飯還是午飯,看看能扛過去那頓。
哈哈哈哈哈,現(xiàn)在想想還挺有意思的,不過這些亂遭的事很多是自己的意識和能力不足時做出的錯誤選擇而導致的。
人那,想開車就要考駕照,想走遠就要有能力。多提升認知,多拓寬眼界!生活的意義就是不斷的更新自己!
謝飛機,小記!
,冬風吹、戰(zhàn)鼓擂。被窩里,誰怕誰。
謝飛機:歪?大哥,你在嗎?
面試官:咋了,大周末的,這么早打電話!?
謝飛機:我夢見,我去谷歌寫JVM了,給你們公司用,之后蹦了,讓我起來改bug!
面試官:啊!?啊,那我問你,JDK 1.8 與 JDK 1.7 在運行時數(shù)據(jù)區(qū)的設計上,你都怎么做的優(yōu)化策略的?
謝飛機:我沒寫這,我不知道!
面試官:擦。。。
如圖 25-1 是 JDK 1.6、1.7、1.8 的內(nèi)存模型演變過程,其實這個內(nèi)存模型就是 JVM 運行時數(shù)據(jù)區(qū)依照JVM虛擬機規(guī)范的具體實現(xiàn)過程。
在圖 25-1 中各個版本的迭代都是為了更好的適應CPU性能提升,最大限度提升的JVM運行效率。這些版本的JVM內(nèi)存模型主要有以下差異:
元空間
。但字符串常量池仍然存放在堆上。以上,就是關于程序計數(shù)器的定義,如果這樣看沒有感覺,我們舉一個例子。
定義一段 Java 方法的代碼,這段代碼是計算圓形的周長。
public static float circumference(float r){
float pi = 3.14f;
float area = 2 * pi * r;
return area;
}
接下來,如圖 25-2 是這段代碼的在虛擬機中的執(zhí)行過程,左側是它的程序計數(shù)器對應的行號。
可能這么只從定義看上去仍然沒有什么感覺,我們再找一個例子。
這是一個關于斐波那契數(shù)列(Fibonacci sequence)
求值的例子,我們通過斐波那契數(shù)列在虛擬機中的執(zhí)行過程,來體會Java虛擬機棧的用途。
斐波那契數(shù)列(Fibonacci sequence),又稱黃金分割數(shù)列、因數(shù)學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數(shù)列”,指的是這樣一個數(shù)列:1、1、2、3、5、8、13、21、34、……在數(shù)學上,斐波納契數(shù)列以如下被以遞推的方法定義:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)在現(xiàn)代物理、準晶體結構、化學等領域,斐波納契數(shù)列都有直接的應用,為此,美國數(shù)學會從1963年起出版了以《斐波納契數(shù)列季刊》為名的一份數(shù)學雜志,用于專門刊載這方面的研究成果。
關于本地方法棧在以上的例子已經(jīng)涉及了這部分內(nèi)容,這里就不在贅述了。
-XX:MetaspaceSize=512M XX:MaxMetaspaceSize=1024M
。教你個小技巧通過jps、jinfo查看元空間,如下:
其他:關于 JDK1.8 元空間的介紹: Move part of the contents of the permanent generation in Hotspot to the Java heap and the remainder to native memory. http://openjdk.java.net/jeps/122
其實以上的內(nèi)容,已經(jīng)完整的介紹了JVM虛擬機的內(nèi)存模型,也就是運行時數(shù)據(jù)區(qū)的結構。但是這東西看完可能就忘記了,因為缺少一個可親手操作的代碼。
所以,這里我給大家用Java代碼寫一段關于數(shù)據(jù)槽、棧幀、局部變量、虛擬機棧以及堆的代碼結構,讓大家更好的加深對虛擬機內(nèi)存模型的印象。
運行時數(shù)據(jù)區(qū)
├── heap
│ ├── constantpool
│ ├── methodarea
│ │ ├── Class.java
│ │ ├── ClassMember.java
│ │ ├── Field.java
│ │ ├── Method.java
│ │ ├── MethodDescriptor.java
│ │ ├── MethodDescriptorParser.java
│ │ ├── MethodLookup.java
│ │ ├── Object.java
│ │ ├── Slots.java
│ │ └── StringPool.java
│ └── ClassLoader.java
├── Frame.java
├── JvmStack.java
├── LocalVars.java
├── OperandStack.java
├── Slot.java
└── Thread.java
以上這部分就是使用Java實現(xiàn)的部分JVM虛擬機功能,這部分主要包括如下內(nèi)容:
操作數(shù)棧 OperandStack
public class OperandStack {
private int size = 0;
private Slot[] slots;
public OperandStack(int maxStack) {
if (maxStack > 0) {
slots = new Slot[maxStack];
for (int i = 0; i < maxStack; i++) {
slots[i] = new Slot();
}
}
}
//...
}
虛擬機棧 OperandStack
public class JvmStack {
private int maxSize;
private int size;
private Frame _top;
//...
}
棧幀 Frame
public class Frame {
//stack is implemented as linked list
Frame lower;
//局部變量表
private LocalVars localVars;
//操作數(shù)棧
private OperandStack operandStack;
private Thread thread;
private Method method;
private int nextPC;
//...
}
每一個方法在執(zhí)行的同時,都會創(chuàng)建出一個棧幀
,是不就對了上,可以真的理解了。用Java實現(xiàn)JVM源碼
:https://github.com/fuzhengwei/itstack-demo-jvm不是說 JDK 1.8 的內(nèi)存模型把永久代下掉,換上元空間
了嗎?但不測試下,就感受不到呀,沒有證據(jù)!
所有關于代碼邏輯的學習,都需要有數(shù)據(jù)基礎和證明過程,這樣才能有深刻的印象。走著,帶你把元空間干滿,讓它OOM!
public static void main(String[] args) throws InterruptedException {
Thread.sleep(5000);
ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MetaSpaceOomMock.class);
enhancer.setCallbackTypes(new Class[]{Dispatcher.class, MethodInterceptor.class});
enhancer.setCallbackFilter(new CallbackFilter() {
@Override
public int accept(Method method) {
return 1;
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
});
System.out.println(enhancer.createClass().getName() + loadingBean.getTotalLoadedClassCount() + loadingBean.getLoadedClassCount() + loadingBean.getUnloadedClassCount());
}
}
Thread.sleep(5000);
,睡一會,方便我們點檢測,要不程序太快就異常了。默認情況下元空間太大了,不方便測試出結果,所以我們把它調(diào)的小一點。
-XX:MetaspaceSize=8m
-XX:MaxMetaspaceSize=80m
基于 jconsole 監(jiān)控,我們需要設置下參數(shù)。
-Djava.rmi.server.hostname=127.0.0.1
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=7397
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
以上的測試參數(shù),配置到IDEA中運行程序里就可以,如下:
另外,jconsole 可以通過 IDEA 提供的 Terminal 啟動,直接輸入 jconsole
,回車即可。
org.itstack.interview.MetaSpaceOomMock$$EnhancerByCGLIB$$bd2bb16e999099900
org.itstack.interview.MetaSpaceOomMock$$EnhancerByCGLIB$$9c774e64999199910
org.itstack.interview.MetaSpaceOomMock$$EnhancerByCGLIB$$cac97732999299920
org.itstack.interview.MetaSpaceOomMock$$EnhancerByCGLIB$$91c6a15a999399930
Exception in thread "main" java.lang.IllegalStateException: Unable to load cache item
at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:79)
at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:119)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:480)
at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:337)
at org.itstack.interview.MetaSpaceOomMock.main(MetaSpaceOomMock.java:34)
Caused by: java.lang.OutOfMemoryError: Metaspace
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:467)
at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)
at net.sf.cglib.proxy.Enhancer.generate(Enhancer.java:492)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:96)
at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:94)
at net.sf.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
... 6 more