自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我們一起聊聊 Java 內(nèi)存泄漏

開(kāi)發(fā) 前端
使用Java編寫(xiě)程序時(shí),我們使用new關(guān)鍵字創(chuàng)建對(duì)象。而且我們還不需要專門(mén)在對(duì)象使用完成后去釋放其占用的內(nèi)存,這是因?yàn)镴ava有專門(mén)的垃圾回收器來(lái)負(fù)責(zé)刪除不需要的對(duì)象。

Java內(nèi)存泄漏一直Java程序中最常見(jiàn)的問(wèn)題之一,它會(huì)導(dǎo)致內(nèi)存溢出,最終導(dǎo)致程序崩潰。我們可能對(duì)內(nèi)存泄漏很熟悉,但又不是那么熟悉,真的遇到事故的時(shí)候,內(nèi)存泄漏問(wèn)題排查起來(lái)卻也沒(méi)有那么容易。本篇就再次梳理一下Java內(nèi)存泄漏的那些事。

前言

使用Java編寫(xiě)程序時(shí),我們使用new關(guān)鍵字創(chuàng)建對(duì)象。而且我們還不需要專門(mén)在對(duì)象使用完成后去釋放其占用的內(nèi)存,這是因?yàn)镴ava有專門(mén)的垃圾回收器來(lái)負(fù)責(zé)刪除不需要的對(duì)象。只要不被使用的對(duì)象有垃圾回收器回收,那么程序會(huì)處于正常運(yùn)行的狀態(tài),但是垃圾回收器無(wú)法刪除那些不被使用的對(duì)象時(shí),我們的Java程序則可能發(fā)生了內(nèi)存泄漏。

內(nèi)存泄漏是什么

內(nèi)存泄漏指的是JVM中某些不再需要使用的對(duì)象,仍然存活于JVM中而不能及時(shí)釋放而導(dǎo)致內(nèi)存空間的浪費(fèi)。Java中內(nèi)存泄漏的原因有多種,這些眾多的因素會(huì)導(dǎo)致Java程序產(chǎn)生不同類型的內(nèi)存泄漏,隨著時(shí)間的推移,內(nèi)存泄漏會(huì)使程序增加額外的內(nèi)存資源占用,從而導(dǎo)致程序性能下降。

垃圾回收器會(huì)回收長(zhǎng)時(shí)間沒(méi)有引用的對(duì)象,但是它不會(huì)回收那些還存在引用的對(duì)象,這就是產(chǎn)生內(nèi)存泄漏的原因。

所以為了防止內(nèi)存泄漏,程序設(shè)計(jì)之初就需要考慮去釋放那些不使用的內(nèi)存空間,而開(kāi)發(fā)人員也應(yīng)當(dāng)時(shí)刻考慮內(nèi)存泄漏的可能性,并增加一些測(cè)試和檢測(cè)避免內(nèi)存泄漏。

堆和棧的內(nèi)存泄漏

Java中,我們可能會(huì)遇到棧內(nèi)存泄露和堆內(nèi)存泄漏。

其中堆內(nèi)存泄漏是由于創(chuàng)建后的對(duì)象一直存在于堆中,不再需要的對(duì)象其引用一直沒(méi)有被移除。這些無(wú)用的對(duì)象會(huì)慢慢占用內(nèi)存,最后導(dǎo)致內(nèi)存溢出。

棧內(nèi)存泄漏由于方法不斷被調(diào)用,但是一直沒(méi)有退出方法。這種情況可能發(fā)生在無(wú)限循環(huán)或遞歸掉用時(shí),最終導(dǎo)致棧內(nèi)存溢出。

內(nèi)存泄漏的原因

Java中內(nèi)存泄漏主要是因?yàn)椴荒苷_釋放不需要的資源,長(zhǎng)生命周期對(duì)象持有短生命周期對(duì)象的引用。

  • 靜態(tài)字段

靜態(tài)字段引起的內(nèi)存泄漏比較常見(jiàn),如果某個(gè)不需要的類中含有靜態(tài)字段,那么就會(huì)造成內(nèi)存泄漏。單例模式中如果持有其他的類引用就會(huì)造成內(nèi)存泄漏,靜態(tài)集合如HashMap,LinkedList等持有的一些對(duì)象沒(méi)有及時(shí)釋放等。

  • Thread Local

threadlocal引用一個(gè)對(duì)象使用完成后并沒(méi)有被及時(shí)remove掉,線程一直存活的情況下(使用線程池時(shí))就會(huì)發(fā)生內(nèi)存泄漏。

大多時(shí)候內(nèi)存泄漏都是由于開(kāi)發(fā)人員的代碼錯(cuò)誤導(dǎo)致的,要防止這種內(nèi)存泄漏,就需要編寫(xiě)必要的代碼來(lái)配合垃圾回收器釋放資源。

避免Java內(nèi)存泄漏的一些最佳實(shí)踐

  • 使用最新穩(wěn)定版本的Java
  • 盡量減少使用靜態(tài)變量,使用完之后及時(shí)賦值 null,移除引用
  • 明確對(duì)象的有效作用域,盡量縮小對(duì)象的作用域。局部變量回收會(huì)很快。
  • 減少長(zhǎng)生命周期對(duì)象持有短生命周期的引用
  • 各種連接應(yīng)該及時(shí)關(guān)閉(數(shù)據(jù)庫(kù)連接,網(wǎng)絡(luò),IO等)
  • 使用內(nèi)存泄漏檢測(cè)工具如MAT,Visual VM,jprofile 等
  • 避免在代碼中使用System.gc()
  • 避免使用內(nèi)部類

內(nèi)存泄漏很難定位并修復(fù),但是我們可以遵循以下幾個(gè)步驟去定位并修復(fù):

  • 確定是否存在內(nèi)存泄漏,啟用詳細(xì)的GC跟蹤。
  • 使用一些第三方插件進(jìn)行分析(jprofile  Visual VM等)
  • 檢查調(diào)用堆棧是否有未釋放的引用(分析GC狀態(tài))
  • 找出對(duì)象沒(méi)有被垃圾回收的原因
  • 編寫(xiě)代碼手動(dòng)刪除此類對(duì)象
責(zé)任編輯:武曉燕 來(lái)源: Java技術(shù)指北
相關(guān)推薦

2023-03-26 23:47:32

Go內(nèi)存模型

2025-03-27 02:00:00

SPIJava接口

2023-08-04 08:20:56

DockerfileDocker工具

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2023-09-10 21:42:31

2023-06-30 08:18:51

敏捷開(kāi)發(fā)模式

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2023-11-10 08:04:43

Java 17Java 11JDK

2022-12-06 08:12:11

Java關(guān)鍵字

2022-02-23 08:41:58

NATIPv4IPv6

2022-09-22 08:06:29

計(jì)算機(jī)平板微信

2024-11-28 09:57:50

C#事件發(fā)布器

2022-10-08 00:00:05

SQL機(jī)制結(jié)構(gòu)

2024-07-26 09:47:28

2023-07-24 09:41:08

自動(dòng)駕駛技術(shù)交通

2021-08-12 07:49:24

mysql

2022-06-26 09:40:55

Django框架服務(wù)

2022-02-14 07:03:31

網(wǎng)站安全MFA
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)