Java:對象的強、軟、弱和虛引用

見:http://zhangjunhd.blog.51cto.com/113473/53092


maven/Java/web/bootstrap/dataTable/app開發QQ群:566862629。希望更多人一起幫助我學習。


1.對象的強、軟、弱和虛引用
JDK 1.2以前的版本中,若一個對象不被任何變量引用,那么程序就無法再使用這個對象。也就是說,只有對象處于可觸及(reachable)狀態,程序才能使用它。從JDK 1.2版本開始,把對象的引用分為4種級別,從而使程序能更加靈活地控制對象的生命周期。這4種級別由高到低依次為:強引用、軟引用、弱引用和虛引用。圖1為對象應用類層次。
圖1
強引用(StrongReference
強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。當內存空間不足,Java虛擬機寧愿拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題。
?
⑵軟引用(SoftReference
如果一個對象只具有軟引用,則內存空間足夠,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存(下文給出示例)。
軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被垃圾回收器回收,Java虛擬機就會把這個軟引用加入到與之關聯的引用隊列中。
?
⑶弱引用(WeakReference
弱引用與軟引用的區別在于:只具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。不過,由于垃圾回收器是一個優先級很低的線程,因此不一定會很快發現那些只具有弱引用的對象。
弱引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果弱引用所引用的對象被垃圾回收,Java虛擬機就會把這個弱引用加入到與之關聯的引用隊列中。
?
⑷虛引用(PhantomReference
虛引用顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用主要用來跟蹤對象被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區別在于:虛引用必須和引用隊列ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之?關聯的引用隊列中。
ReferenceQueue?queue?=?new?ReferenceQueue ();
PhantomReference?pr?=?new?PhantomReference (object,?queue);
程序可以通過判斷引用隊列中是否已經加入了虛引用,來了解被引用的對象是否將要被垃圾回收。如果程序發現某個虛引用已經被加入到引用隊列,那么就可以在所引用的對象的內存被回收之前采取必要的行動。
2.對象可及性的判斷
????在很多時候,一個對象并不是從根集直接引用的,而是一個對象被其他對象引用,甚至同時被幾個對象所引用,從而構成一個以根集為頂的樹形結構。如圖2所示
????在這個樹形的引用鏈中,箭頭的方向代表了引用的方向,所指向的對象是被引用對象。由圖可以看出,從根集到一個對象可以由很多條路徑。比如到達對象5的路徑就有①-⑤,③-⑦兩條路徑。由此帶來了一個問題,那就是某個對象的可及性如何判斷:
◆單條引用路徑可及性判斷:在這條路徑中,最弱的一個引用決定對象的可及性。
◆多條引用路徑可及性判斷:幾條路徑中,最強的一條的引用決定對象的可及性。
????比如,我們假設圖2中引用①和③為強引用,⑤為軟引用,⑦為弱引用,對于對象5按照這兩個判斷原則,路徑①-⑤取最弱的引用⑤,因此該路徑對對象5的引用為軟引用。同樣,③-⑦為弱引用。在這兩條路徑之間取最強的引用,于是對象5是一個軟可及對象。
3.使用軟引用構建敏感數據的緩存
3.1?為什么需要使用軟引用
???首先,我們看一個雇員信息查詢系統的實例。我們將使用一個Java語言實現的雇員信息查詢系統查詢存儲在磁盤文件或者數據庫中的雇員人事檔案信息。作為一個用戶,我們完全有可能需要回頭去查看幾分鐘甚至幾秒鐘前查看過的雇員檔案信息(同樣,我們在瀏覽WEB頁面的時候也經常會使用“后退”按鈕)。這時我們通常會有兩種程序實現方式:一種是把過去查看過的雇員信息保存在內存中,每一個存儲了雇員檔案信息的Java對象的生命周期貫穿整個應用程序始終;另一種是當用戶開始查看其他雇員的檔案信息的時候,把存儲了當前所查看的雇員檔案信息的Java對象結束引用,使得垃圾收集線程可以回收其所占用的內存空間,當用戶再次需要瀏覽該雇員的檔案信息的時候,重新構建該雇員的信息。很顯然,第一種實現方法將造成大量的內存浪費,而第二種實現的缺陷在于即使垃圾收集線程還沒有進行垃圾收集,包含雇員檔案信息的對象仍然完好地保存在內存中,應用程序也要重新構建一個對象。我們知道,訪問磁盤文件、訪問網絡資源、查詢數據庫等操作都是影響應用程序執行性能的重要因素,如果能重新獲取那些尚未被回收的Java對象的引用,必將減少不必要的訪問,大大提高程序的運行速度。
?
3.2?如果使用軟引用
SoftReference的特點是它的一個實例保存對一個Java對象的軟引用,該軟引用的存在不妨礙垃圾收集線程對該Java對象的回收。也就是說,一旦SoftReference保存了對一個Java對象的軟引用后,在垃圾線程對這個Java對象回收前,SoftReference類所提供的get()方法返回Java對象的強引用。另外,一旦垃圾線程回收該Java對象之后,get()方法將返回null
看下面代碼:
MyObject?aRef?=?new??MyObject();
SoftReference?aSoftRef=new?SoftReference(aRef);
????此時,對于這個MyObject對象,有兩個引用路徑,一個是來自SoftReference對象的軟引用,一個來自變量aReference的強引用,所以這個MyObject對象是強可及對象。
隨即,我們可以結束aReference對這個MyObject實例的強引用:
aRef?=?null;
此后,這個MyObject對象成為了軟可及對象。如果垃圾收集線程進行內存垃圾收集,并不會因為有一個SoftReference對該對象的引用而始終保留該對象。Java虛擬機的垃圾收集線程對軟可及對象和其他一般Java對象進行了區別對待:軟可及對象的清理是由垃圾收集線程根據其特定算法按照內存需求決定的。也就是說,垃圾收集線程會在虛擬機拋出OutOfMemoryError之前回收軟可及對象,而且虛擬機會盡可能優先回收長時間閑置不用的軟可及對象,對那些剛剛構建的或剛剛使用過的“新”軟可反對象會被虛擬機盡可能保留。在回收這些對象之前,我們可以通過:
MyObject?anotherRef=(MyObject)aSoftRef.get();
????重新獲得對該實例的強引用。而回收之后,調用get()方法就只能得到null了。
?
3.3?使用ReferenceQueue清除失去了軟引用對象的SoftReference
作為一個Java對象,SoftReference對象除了具有保存軟引用的特殊性之外,也具有Java對象的一般性。所以,當軟可及對象被回收之后,雖然這個SoftReference對象的get()方法返回null,但這個SoftReference對象已經不再具有存在的價值,需要一個適當的清除機制,避免大量SoftReference對象帶來的內存泄漏。在java.lang.ref包里還提供了ReferenceQueue。如果在創建SoftReference對象的時候,使用了一個ReferenceQueue對象作為參數提供給SoftReference的構造方法,如:
ReferenceQueue?queue?=?new??ReferenceQueue();
SoftReference??ref=new??SoftReference(aMyObject,?queue);
????那么當這個SoftReference所軟引用的aMyOhject被垃圾收集器回收的同時,ref所強引用的SoftReference對象被列入ReferenceQueue。也就是說,ReferenceQueue中保存的對象是Reference對象,而且是已經失去了它所軟引用的對象的Reference對象。另外從ReferenceQueue這個名字也可以看出,它是一個隊列,當我們調用它的poll()方法的時候,如果這個隊列中不是空隊列,那么將返回隊列前面的那個Reference對象。
在任何時候,我們都可以調用ReferenceQueuepoll()方法來檢查是否有它所關心的非強可及對象被回收。如果隊列為空,將返回一個null,否則該方法返回隊列中前面的一個Reference對象。利用這個方法,我們可以檢查哪個SoftReference所軟引用的對象已經被回收。于是我們可以把這些失去所軟引用的對象的SoftReference對象清除掉。常用的方式為:
SoftReference ref =?null;
while?((ref = (EmployeeRef)?q.poll()) !=?null) {
????//?清除ref
}
理解了ReferenceQueue的工作機制之后,我們就可以開始構造一個Java對象的高速緩存器了。
?
3.4通過軟可及對象重獲方法實現Java對象的高速緩存
????利用Java2平臺垃圾收集機制的特性以及前述的垃圾對象重獲方法,我們通過一個雇員信息查詢系統的小例子來說明如何構建一種高速緩存器來避免重復構建同一個對象帶來的性能損失。我們將一個雇員的檔案信息定義為一個Employee:
public?class?Employee {
????private?String?id;//?雇員的標識號碼
????private?String?name;//?雇員姓名
????private?String?department;//?該雇員所在部門
????private?String?Phone;//?該雇員聯系電話
????private?int?salary;//?該雇員薪資
????private?String?origin;//?該雇員信息的來源
?
????//?構造方法
????public?Employee(String id) {
???????this.id?= id;
???????getDataFromlnfoCenter();
????}
?
????//?到數據庫中取得雇員信息
????private?void?getDataFromlnfoCenter() {
???????//?和數據庫建立連接井查詢該雇員的信息,將查詢結果賦值
???????//?namedepartmentplonesalary等變量
???????//?同時將origin賦值為"From DataBase"
????}
……
這個Employee類的構造方法中我們可以預見,如果每次需要查詢一個雇員的信息。哪怕是幾秒中之前剛剛查詢過的,都要重新構建一個實例,這是需要消耗很多時間的。下面是一個對Employee對象進行緩存的緩存器的定義:
import?java.lang.ref.ReferenceQueue;
import?java.lang.ref.SoftReference;
import?java.util.Hashtable;
public?class?EmployeeCache {
????static?private?EmployeeCache?cache;//?一個Cache實例
????private?Hashtable<String,EmployeeRef>?employeeRefs;//?用于Chche內容的存儲
????private?ReferenceQueue<Employee>?q;//?垃圾Reference的隊列
?
????//?繼承SoftReference,使得每一個實例都具有可識別的標識。
????//?并且該標識與其在HashMap內的key相同。
????private?class?EmployeeRef?extends?SoftReference<Employee> {
???????private?String?_key?=?"";
?
???????public?EmployeeRef(Employee em, ReferenceQueue<Employee> q) {
???????????super(em, q);
???????????_key?= em.getID();
???????}
????}
?
????//?構建一個緩存器實例
????private?EmployeeCache() {
???????employeeRefs?=?new?Hashtable<String,EmployeeRef>();
???????q?=?new?ReferenceQueue<Employee>();
????}
?
????//?取得緩存器實例
????public?static?EmployeeCache getInstance() {
???????if?(cache?==?null) {
???????????cache?=?new?EmployeeCache();
???????}
???????return?cache;
????}
?
????//?以軟引用的方式對一個Employee對象的實例進行引用并保存該引用
????private?void?cacheEmployee(Employee em) {
???????cleanCache();//?清除垃圾引用
???????EmployeeRef ref =?new?EmployeeRef(em,?q);
???????employeeRefs.put(em.getID(), ref);
????}
?
????//?依據所指定的ID號,重新獲取相應Employee對象的實例
????public?Employee getEmployee(String ID) {
???????Employee em =?null;
???????//?緩存中是否有該Employee實例的軟引用,如果有,從軟引用中取得。
???????if?(employeeRefs.containsKey(ID)) {
???????????EmployeeRef ref = (EmployeeRef)?employeeRefs.get(ID);
???????????em = (Employee) ref.get();
???????}
???????//?如果沒有軟引用,或者從軟引用中得到的實例是null,重新構建一個實例,
???????//?并保存對這個新建實例的軟引用
???????if?(em ==?null) {
???????????em =?new?Employee(ID);
???????????System.out.println("Retrieve From EmployeeInfoCenter. ID="?+ ID);
???????????this.cacheEmployee(em);
???????}
???????return?em;
????}
?
????//?清除那些所軟引用的Employee對象已經被回收的EmployeeRef對象
????private?void?cleanCache() {
???????EmployeeRef ref =?null;
???????while?((ref = (EmployeeRef)?q.poll()) !=?null) {
???????????employeeRefs.remove(ref._key);
???????}
????}
?
????//?清除Cache內的全部內容
????public?void?clearCache() {
???????cleanCache();
???????employeeRefs.clear();
???????System.gc();
???????System.runFinalization();
????}
}
4.使用弱引用構建非敏感數據的緩存
4.1全局?Map?造成的內存泄漏
無意識對象保留最常見的原因是使用Map將元數據與臨時對象(transient object)相關聯。假定一個對象具有中等生命周期,比分配它的那個方法調用的生命周期長,但是比應用程序的生命周期短,如客戶機的套接字連接。需要將一些元數據與這個套接字關聯,如生成連接的用戶的標識。在創建Socket時是不知道這些信息的,并且不能將數據添加到Socket對象上,因為不能控制?Socket?類或者它的子類。這時,典型的方法就是在一個全局?Map?中存儲這些信息,如下面的?SocketManager?類所示:使用一個全局 Map 將元數據關聯到一個對象。
public?class?SocketManager {
????private?Map<Socket, User>?m?=?new?HashMap<Socket, User>();
?
????public?void?setUser(Socket s, User u) {
???????m.put(s, u);
????}
?
????public?User getUser(Socket s) {
???????return?m.get(s);
????}
?
????public?void?removeUser(Socket s) {
???????m.remove(s);
????}
}
這種方法的問題是元數據的生命周期需要與套接字的生命周期掛鉤,但是除非準確地知道什么時候程序不再需要這個套接字,并記住從?Map?中刪除相應的映射,否則,Socket??User?對象將會永遠留在?Map?中,遠遠超過響應了請求和關閉套接字的時間。這會阻止?Socket??User?對象被垃圾收集,即使應用程序不會再使用它們。這些對象留下來不受控制,很容易造成程序在長時間運行后內存爆滿。除了最簡單的情況,在幾乎所有情況下找出什么時候?Socket?不再被程序使用是一件很煩人和容易出錯的任務,需要人工對內存進行管理。
?
4.2如何使用WeakHashMap
Java集合中有一種特殊的Map類型—WeakHashMap,在這種Map中存放了鍵對象的弱引用,當一個鍵對象被垃圾回收器回收時,那么相應的值對象的引用會從Map中刪除。WeakHashMap能夠節約存儲空間,可用來緩存那些非必須存在的數據。關于Map接口的一般用法。
下面示例中MapCache類的main()方法創建了一個WeakHashMap對象,它存放了一組Key對象的弱引用,此外main()方法還創建了一個數組對象,它存放了部分Key對象的強引用。
import?java.util.WeakHashMap;
?
class?Element {
????private?String?ident;
?
????public?Element(String id) {
???????ident?= id;
????}
?
????public?String toString() {
???????return?ident;
????}
?
????public?int?hashCode() {
???????return?ident.hashCode();
????}
?
????public?boolean?equals(Object obj) {
???????return?obj?instanceof?Element &&?ident.equals(((Element) obj).ident);
????}
???
????protected?void?finalize(){
???????System.out.println("Finalizing "+getClass().getSimpleName()+" "+ident);
????}
}
?
class?Key?extends?Element{
????public?Key(String id){
???????super(id);
????}
}
?
class?Value?extends?Element{
????public?Value (String id){
???????super(id);
????}
}
?
public?class?CanonicalMapping {
????public?static?void?main(String[] args){
???????int?size=1000;
???????Key[] keys=new?Key[size];
???????WeakHashMap<Key,Value> map=new?WeakHashMap<Key,Value>();
???????for(int?i=0;i<size;i++){
???????????Key k=new?Key(Integer.toString(i));
???????????Value v=new?Value(Integer.toString(i));
???????????if(i%3==0)
??????????????keys[i]=k;
???????????map.put(k, v);
???????}
???????System.gc();
????}
}
從打印結果可以看出,當執行System.gc()方法后,垃圾回收器只會回收那些僅僅持有弱引用的Key對象。id可以被3整除的Key對象持有強引用,因此不會被回收。
?
4.3?WeakHashMap?堵住泄漏
?SocketManager?中防止泄漏很容易,只要用?WeakHashMap?代替?HashMap?就行了。(這里假定SocketManager不需要線程安全)。當映射的生命周期必須與鍵的生命周期聯系在一起時,可以使用這種方法。用WeakHashMap修復?SocketManager
public?class?SocketManager {
????private?Map<Socket,User>?m?=?new?WeakHashMap<Socket,User>();
???
????public?void?setUser(Socket s, User u) {
????????m.put(s, u);
????}
????public?User getUser(Socket s) {
????????return?m.get(s);
????}
}
?
4.4配合使用引用隊列
WeakHashMap?用弱引用承載映射鍵,這使得應用程序不再使用鍵對象時它們可以被垃圾收集,get()?實現可以根據?WeakReference.get()?是否返回?null?來區分死的映射和活的映射。但是這只是防止?Map?的內存消耗在應用程序的生命周期中不斷增加所需要做的工作的一半,還需要做一些工作以便在鍵對象被收集后從?Map?中刪除死項。否則,Map?會充滿對應于死鍵的項。雖然這對于應用程序是不可見的,但是它仍然會造成應用程序耗盡內存。
引用隊列是垃圾收集器向應用程序返回關于對象生命周期的信息的主要方法。弱引用有個構造函數取引用隊列作為參數。如果用關聯的引用隊列創建弱引用,在弱引用對象成為?GC?候選對象時,這個引用對象就在引用清除后加入到引用隊列中(具體參考上文軟引用示例)。
WeakHashMap?有一個名為?expungeStaleEntries()?的私有方法,大多數?Map?操作中會調用它,它去掉引用隊列中所有失效的引用,并刪除關聯的映射。
5UML:使用關聯類指明特定形式的引用
關聯類能夠用來指明特定形式的引用,如弱(weak)、軟(soft)或虛?phantom)引用。
也可以如下的構造型方式。
6.參考資料
[1]Thinking in Java4th
[2]孫衛琴,Java面向對象編程,電子工業出版社,2006
[3]Robert Martin,UML for java programmers,2004
[4]?通過Java軟可及對象的重獲提高程序性能,張立明,陳朔鷹,程序員,200308
[5] Monica PawlanReference Objects and Garbage Collection,
[url]http://java.sun.com/developer/technicalArticles/ALT/RefObj/[/url]
[6]Brian Goetz,Java?理論與實踐:?用弱引用堵住內存泄漏,

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451260.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451260.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451260.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java注解:@Deprecated(不建議使用的,廢棄的);@SuppressWarnings(忽略警告,達到抑制編譯器產生警告的目的)

java注解&#xff1a;Deprecated(不建議使用的&#xff0c;廢棄的), SuppressWarnings(忽略警告&#xff0c;達到抑制編譯器產生警告的目的)Deprecated可以修飾類、方法、變量&#xff0c;在java源碼中被Deprecated修飾的類、方法、變量等表示不建議使用的&#xff0c;可能會出…

Mysql 替換字段的一部分內容

UPDATE 表名 SET 字段名 REPLACE( 替換前的字段值, 替換前關鍵字, 替換后關鍵字 ) WHERE 字段名 REGEXP "替換前的字段值"; 例子&#xff1a; UPDATE user SET mobile REPLACE( head_img, "http://7xswdm.com1.z0.glb.clouddn.com", "http://qiniu-i…

聊聊3種最常見的響應式設計問題

響應式設計方法對開發者非常有用&#xff0c;因為它使我們的內容在各種設備上廣為傳播。不用保留幾個獨立版本的網站&#xff0c;也可以摒除諸如縮放和流式布局這些方法的弊端。 縮放、流式布局與響應式 這些術語容易造成混淆&#xff0c;設計師常常錯誤地交替互用。實際上&…

PV、TPS、QPS是什么

pv 是指頁面被瀏覽的次數&#xff0c;比如你打開一網頁&#xff0c;那么這個網站的pv就算加了一次&#xff1b;tps是每秒內的事務數&#xff0c;比如執行了dml操作&#xff0c;那么相應的tps會增加&#xff1b;qps是指每秒內查詢次數&#xff0c;比如執行了select操作&#xff…

AOP原理解析及Castle、Autofac、Unity框架使用

轉自&#xff1a;https://www.cnblogs.com/neverc/p/5241466.html AOP介紹 面向切面編程&#xff08;Aspect Oriented Programming,英文縮寫為AOP&#xff09;&#xff0c;通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。 AOP是OOP的延續&#xff0c;是軟件…

bootstrap validator 提供了哪些驗證函數

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 目前提供的校驗方法有&#xff1a; "notEmpty" : "不能為空", "password" : "請輸入正確的密碼&q…

帕累托分布(Pareto distributions)、馬太效應

什么是帕累托分布 帕累托分布是以意大利經濟學家維弗雷多帕雷托命名的。 是從大量真實世界的現象中發現的冪次定律分布。這個分布在經濟學以外&#xff0c;也被稱為布拉德福分布。 帕累托因對意大利20%的人口擁有80%的財產的觀察而著名&#xff0c;后來被約瑟夫朱蘭和其他人概括…

兩個class寫在同一個java文件中

第一種&#xff1a; 一個public類&#xff0c;多個非public類&#xff0c;例如&#xff1a;public class A&#xff5b;&#xff5d;class B&#xff5b;&#xff5d;第二個class前面不能加public。 第二種&#xff1a; 第二種是內部類&#xff0c;寫在公共類體里面的&#xff…

微信小程序的一些數據調用方式

1.模板數據的調用 一張圖了解一下在wxml頁調用預先定義好的模板&#xff1a; 可以看到上面調用了兩個模板&#xff0c;數據調用卻是不同的&#xff0c;obj是一個對象&#xff0c;對象內包含多個鍵值對形式的數據&#xff1b; tabbar是一個一維數組&#xff0c;每個數組項又都是…

手機廠商探路互聯網:硬件高利潤時代已成歷史

華為消費者業務集團CEO兼終端公司董事長余承東近日出席“2012年全球移動互聯網大會”期間證實&#xff0c;華為計劃與奇虎360合作推出一款智能手機。 余承東表示&#xff0c;華為終端將嘗試與多家互聯網公司就智能手機業務展開合作&#xff0c;但他未透露與奇虎360合作的更多細…

解決:按截圖 ctrl+alt+a QQ聊天窗口就自動最小化(QQ以外的可以截圖)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、問題如題 &#xff0c;想截圖QQ聊天記錄都不行 二、 解決方法&#xff1a; 如圖找到QQ截圖按鈕&#xff0c;點擊下拉倒三角&…

數據庫備份DBS商業化發布

數據庫備份DBS商業化發布將在2018年7月11日 15:00-16:00直播&#xff0c;敬請關注&#xff01; 數據庫備份DBS為數據庫提供連續數據保護、低成本的備份服務。 它可以為多種環境的數據提供強有力的保護&#xff0c;包括企業數據中心、其他云廠商及公共云。數據庫備份提供數據備份…

堡壘機(跳板機)

堡壘機&#xff08;跳板機&#xff09;&#xff1f;現在一定規模互聯網企業&#xff0c;往往都擁有大量服務器&#xff0c;如何安全并高效的管理這些服務器是每個系統運維或安全運維人員必要工作。現在比較常見的方案是搭建堡壘機環境作為線上服務器的入口&#xff0c;所有服務…

2018-09-18

12.1 LNMP架構介紹 和LAMP不同的是&#xff0c;提供web服務的是Nginx并且php是作為一個獨立服務存在的&#xff0c;這個服務叫做php-fpmNginx直接處理靜態請求&#xff0c;動態請求會轉發給php-fpm12.2 MySQL安裝 二進制免編譯包安裝 [rootlocalhost ~]# cd /usr/local/src/ [r…

舉例說明Java中代碼塊的執行順序

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 結論 這里先把整理好的結論拋給大家&#xff0c;然后我在寫個程序來驗證我們的結論。在Java類被new的過程中&#xff0c;執行順序如…

Google 正式開源 Jib ,幫助 Java 應用快速容器化

Google 本周宣布開源一款新的 Java 工具 Jib &#xff0c;旨在讓開發者使用他們熟悉的工具更輕松地將 Java 應用程序容器化。在7月9日發布的博客文章中&#xff0c;Google 軟件工程師 Appu Goundan 和 Qingyang Chen 將 Jib 描述為一個容器鏡像構建器&#xff0c;旨在處理將 Ja…

“公敵”京東:眾同行將其拖入價格戰

倒京東語錄 當當網董事長李國慶&#xff1a; 京東的資金只能維持到8月至12月。當當網是賺一個花兩個&#xff0c;而京東則是賺一個花四個。 蘇寧電器董事長張近東&#xff1a; 我至今沒有看見過哪個企業能通過這種方式取得最后勝利。這種違背正常商業邏輯的做法&#xff0c…

跨域與跨域訪問

什么是跨域 跨域是指從一個域名的網頁去請求另一個域名的資源。比如從www.baidu.com 頁面去請求 www.google.com 的資源。跨域的嚴格一點的定義是&#xff1a;只要 協議&#xff0c;域名&#xff0c;端口有任何一個的不同&#xff0c;就被當作是跨域 為什么瀏覽器要限制跨域訪…

thymeleaf 使用javascript定義數組報錯

js中免不了的要用的數組&#xff0c;一維的二維的三維的 但是當用到thymeleaf作為模版時候會有一些坑&#xff0c;導致數組不能用 org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "{checkbox: true, fixed: true}, {field: origi…

解決:Failed to execute goal on project aopcore: Could not resolve dependencies for project com.cmos:

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、問題描述 maven工程 jar包無法下載&#xff0c;報錯如下 &#xff1a; [ERROR] Failed to execute goal on project aopcore: Cou…