前言
分享一个很好用的jdk自带的工具 jmap
这个工具可以查看内存中的配置以及占用信息
提示:以下是本篇文章正文内容,下面案例可供参考
使用步骤
写个程序测试一下jmap的威力
public class Test {
public static void main(String[] args) {
while (true){//不让main线程结束.让他一直循环
}
}
}
Run起来之后,我们在IDEA的终端或者cd到程序目录,之后使用:jps命令找到当前进程号
F:\code\Projection\test>jps
13328 Launcher
13792 KotlinCompileDaemon
17348 Test
7832 RemoteMavenServer36
11260 Jps
14316
找到当前的进程号是:17348
然后通过jmap -heap 17348可以得到堆内存的配置以及占用情况
我使用的是jdk1.8
F:\code\Projection\test>jmap -heap 17164
Attaching to process ID 17164, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration: 堆初始化内存配置
MinHeapFreeRatio = 0 堆最小空闲比率
MaxHeapFreeRatio = 100 堆最大空闲比率
MaxHeapSize = 6421479424 (6124.0MB) 堆最大空间
NewSize = 134217728 (128.0MB) 新生代默认空间
MaxNewSize = 2140143616 (2041.0MB) 新生代最大内存空间
OldSize = 268435456 (256.0MB) 老年代默认内存空间
NewRatio = 2 (默认)新生代:老年代 = 1:2
SurvivorRatio = 8 (默认)伊甸园区:from:to = 8:1:1
MetaspaceSize = 21807104 (20.796875MB) 1.8的元空间默认大小
CompressedClassSpaceSize = 1073741824 (1024.0MB) 开启了指针压缩?后续研究一下
MaxMetaspaceSize = 17592186044415 MB 元空间最大限制大小
G1HeapRegionSize = 0 (0.0MB) G1 堆区域大小
Heap Usage: 堆的使用情况
PS Young Generation 新生代
Eden Space: Eden区
capacity = 100663296 (96.0MB) 容量
used = 10066464 (9.600128173828125MB) 已使用容量
free = 90596832 (86.39987182617188MB) 剩余容量
10.000133514404297% used 已使用内存占比
From Space: from区
capacity = 16777216 (16.0MB)
used = 0 (0.0MB)
free = 16777216 (16.0MB)
0.0% used
To Space: to区
capacity = 16777216 (16.0MB)
used = 0 (0.0MB)
free = 16777216 (16.0MB)
0.0% used
PS Old Generation 老年代
capacity = 268435456 (256.0MB)
used = 0 (0.0MB)
free = 268435456 (256.0MB)
0.0% used
3192 interned Strings occupying 282552 bytes. 字符串占用内存情况
最后一句
3192 interned Strings occupying 282552 bytes.
当前有3192个字符串对象,共占JVM内存282552字节,约275.9KB,0.27M
试试如果添加一条字面量,那么这个字面量在1.8中会存在哪里?
public class Test {
public static void main(String[] args) {
String a = "a"; 这里新增了一个字面量"a"
while (true){
}
}
}
我们再来看看jmp打印出的堆内存信息
Attaching to process ID 17348, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.271-b09
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 6421479424 (6124.0MB)
NewSize = 134217728 (128.0MB)
MaxNewSize = 2140143616 (2041.0MB)
OldSize = 268435456 (256.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 100663296 (96.0MB)
used = 10066464 (9.600128173828125MB)
free = 90596832 (86.39987182617188MB)
10.000133514404297% used
From Space:
capacity = 16777216 (16.0MB)
used = 0 (0.0MB)
free = 16777216 (16.0MB)
0.0% used
To Space:
capacity = 16777216 (16.0MB)
used = 0 (0.0MB)
free = 16777216 (16.0MB)
0.0% used
PS Old Generation
capacity = 268435456 (256.0MB)
used = 0 (0.0MB)
free = 268435456 (256.0MB)
0.0% used
3193 interned Strings occupying 282600 bytes.
题外话:
发现前面都相同,但最后这个String对象+1,并且多占用了48字节??
3193 interned Strings occupying 282600 bytes.
String a = "a";
…
之后又试了试增加一个String b = “b”;的字面量,然后打印信息发现
3194 interned Strings occupying 282648 bytes. 怎么又多了48bytes??
String a = "a";
String b = "b";
再试试,下面这个“ab”,发现占用内存又回到了和“a”的时候一致
3193 interned Strings occupying 282600 bytes.
String a = "ab";
其实按说一个英文字符是1个字节,那么“a”应该就一字节,“ab”应该是两字节大小
一直试到"abcd"都是 282600 bytes
直到下面的"abcde"发现又多了8字节??
3193 interned Strings occupying 282608 bytes.
String a = "abcde";
其原因后来研究发现是因为String的凑整 String对象究竟占多少字节?
————— END —————