当前位置:网站首页>[100 cases of JVM tuning practice] 05 - Method area tuning practice (Part 2)
[100 cases of JVM tuning practice] 05 - Method area tuning practice (Part 2)
2022-07-07 01:06:00 【Half old 518】
front said
Author's brief introduction : Half old 518, Long distance runner , Determined to persist in writing 10 Blog of the year , Focus on java Back end
Column Introduction : Case driven introduction JVM knowledge , Teach you how to use JVM Troubleshooting 、 Evaluation code 、 Optimize performance
The article brief introduction : Introduce the concept of method area 、 Help you deeply sort out direct memory
7.8 Direct memory
Direct memory is managed by the operating system . Common in NIO, For data buffering , High read and write performance , Allocation and recycling costs are high .
Use the following code to compare reading and writing using traditional methods with NIO The difference between reading and writing , Note that the first time you start reading and writing, the performance will be poor , Need to run several more times , Calculate average .
/**
* demonstration ByteBuffer effect
*/
public class Demo1_9 {
static final String FROM = "F:\\ Blog \\ Grain college practice program .md";
static final String TO = "F:\\ Grain college practice program .md";
static final int _1Mb = 1024 * 1024;
public static void main(String[] args) {
io(); // io when :1535.586957 1766.963399 1359.240226
directBuffer(); // directBuffer when :479.295165 702.291454 562.56592
}
private static void directBuffer() {
long start = System.nanoTime();
try (FileChannel from = new FileInputStream(FROM).getChannel();
FileChannel to = new FileOutputStream(TO).getChannel();
) {
ByteBuffer bb = ByteBuffer.allocateDirect(_1Mb);
while (true) {
int len = from.read(bb);
if (len == -1) {
break;
}
bb.flip();
to.write(bb);
bb.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
long end = System.nanoTime();
System.out.println("directBuffer when :" + (end - start) / 1000_000.0);
}
private static void io() {
long start = System.nanoTime();
try (FileInputStream from = new FileInputStream(FROM);
FileOutputStream to = new FileOutputStream(TO);
) {
byte[] buf = new byte[_1Mb];
while (true) {
int len = from.read(buf);
if (len == -1) {
break;
}
to.write(buf, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
long end = System.nanoTime();
System.out.println("io when :" + (end - start) / 1000_000.0);
}
}
Why is the efficiency of direct memory reading and writing high ? Use blocking io To read and write cpu The changes of and memory are shown in the figure below . Obviously , Copy files from the system cache to java A cache is a time-consuming and unnecessary replication .
Use Nio To read and write cpu The changes of and memory are shown in the figure below . Operating system in allocateDirect() Method will allocate a piece of direct memory , This part of memory java Both the code and the system can be accessed .
7.9 Memory overflow of direct memory
Direct memory direct memory It's not up to jvm Garbage collection , May cause memory leak problems . Run the following code .
/**
* Demonstrate direct memory overflow
*/
public class Demo1_10 {
static int _100Mb = 1024 * 1024 * 100;
public static void main(String[] args) {
List<ByteBuffer> list = new ArrayList<>();
int i = 0;
try {
while (true) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_100Mb);
list.add(byteBuffer);
i++;
}
} finally {
System.out.println(i);
}
// The method area is jvm standard , jdk6 The implementation of the method area in is called permanent generation
// jdk8 The implementation of the method area is called meta space
}
}
Output results .
72
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:695)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
at cn.itcast.jvm.t1.direct.Demo1_10.main(Demo1_10.java:19)
What is the underlying recycling mechanism of direct memory ? Run the following code .
/**
* The impact of disabling explicit recycling on direct memory
*/
public class Demo1_26 {
static int _1Gb = 1024 * 1024 * 1024;
/*
* -XX:+DisableExplicitGC Explicit
*/
public static void main(String[] args) throws IOException {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_1Gb);
System.out.println(" Distribution finished ...");
System.in.read();
System.out.println(" Start releasing ...");
byteBuffer = null;
System.gc(); // Explicit garbage collection ,Full GC
System.in.read();
}
}
After the console output is allocated , The memory usage can be seen from the task manager in the background .
When entering enter on the console , The output begins to release , Enter enter again , This occupancy 1 individual G The process of memory is cleaned up . Does it mean java Of gc The operation works ?
Let's analyze the above process of direct memory recovery .Unsafe yes jdk A class at the bottom , For memory allocation , Memory recovery, etc , Ordinary programmers don't need to use , Here we get... Through reflection Unsafe object , Demonstrate the underlying principle of direct memory allocation .
/**
* The underlying principle of direct memory allocation :Unsafe
*/
public class Demo1_27 {
static int _1Gb = 1024 * 1024 * 1024;
public static void main(String[] args) throws IOException {
Unsafe unsafe = getUnsafe();
// Allocate memory
long base = unsafe.allocateMemory(_1Gb);
unsafe.setMemory(base, _1Gb, (byte) 0);
System.in.read();
// Free memory
unsafe.freeMemory(base);
System.in.read();
}
public static Unsafe getUnsafe() {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
return unsafe;
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Run code , Observe in the task manager jdk Process memory usage found , Memory usage will be in allocateMemory() Add... After 1G, stay freeMemory() After recovery . therefore , Direct memory recycling is not actually caused by jvm Virtual machine complete , But through Unsafe Object call freeMemory() complete .
See below ByteBuffer Class to verify our point of view .
allocateDirect() Back to one DirectByteBuffer object .
public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}
call Unsafe in allocateMemory() To apply for memory , newly build Cleaner Object to free memory .
DirectByteBuffer(int cap) { // package-private
super(-1, 0, cap, cap);
boolean pa = VM.isDirectMemoryPageAligned();
int ps = Bits.pageSize();
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
Bits.reserveMemory(size, cap);
long base = 0;
try {
base = unsafe.allocateMemory(size);
} catch (OutOfMemoryError x) {
Bits.unreserveMemory(size, cap);
throw x;
}
unsafe.setMemory(base, size, (byte) 0);
if (pa && (base % ps != 0)) {
// Round up to page boundary
address = base + ps - (base & (ps - 1));
} else {
address = base;
}
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
att = null;
}
cleaner Relating to Deallocator What is it? ? Click in and see that it has been realized Runnable, Is the callback task object , stay run Method is called Unsafe Of freeMemory.
private static class Deallocator
implements Runnable
{
private static Unsafe unsafe = Unsafe.getUnsafe();
private long address;
private long size;
private int capacity;
private Deallocator(long address, long size, int capacity) {
assert (address != 0);
this.address = address;
this.size = size;
this.capacity = capacity;
}
public void run() {
if (address == 0) {
// Paranoia
return;
}
unsafe.freeMemory(address);
address = 0;
Bits.unreserveMemory(size, capacity);
}
}
So when was the garbage collection task performed ? see Cleaner Source code .
public class Cleaner
extends PhantomReference<Object> {
//...
public void clean() {
if (!remove(this))
return;
try {
thunk.run();
} catch (final Throwable x) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
if (System.err != null)
new Error("Cleaner terminated abnormally", x)
.printStackTrace();
System.exit(1);
return null;
}});
}
}
//...
}
original Cleaner yes java Virtual reference type in , When its bound object is garbage collected , Will trigger a virtual reference clean() Method , Execute callback method run().
Now look back DirectByteBuffer Class Cleaner establish , The process is clear .
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
Summarize direct memory allocation 、 The process of release is : By calling Unsafe Of allocateMemory To allocate direct memory , By creating a virtual reference object Cleaner object , take DirectoryByteBuffer Bind with callback task , When Directory When it's recycled , Automatically Cleaner Of clean() Method , To call Unsafe Of freeMemory() Free memory .
7.10 The impact of disabling explicit garbage collection on direct memory
stay java Can be used in System.gc() To make explicit suggestions jvm Garbage collection , But this way of garbage collection is Full GC, It will be recycled in the new generation , Old age recycling will also be carried out . May affect program performance . To avoid misuse by programmers , have access to -XX +DisableExplctGC
To disable the garbage collection of the display .
Run again with explicit garbage collection disabled Demo1_26.
/**
* The impact of disabling explicit recycling on direct memory
*/
public class Demo1_26 {
static int _1Gb = 1024 * 1024 * 1024;
/*
* -XX:+DisableExplicitGC Explicit
*/
public static void main(String[] args) throws IOException {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(_1Gb);
System.out.println(" Distribution finished ...");
System.in.read();
System.out.println(" Start releasing ...");
byteBuffer = null;
System.gc(); // Explicit garbage collection ,Full GC
System.in.read();
}
}
The direct memory of the above code is not recycled , This is because explicit garbage collection fails .bytebuffer Will not be recycled , As a result, the direct memory cannot be released , Only when the program is passive Full GC Garbage collection . If the program needs to use direct memory frequently , We can receive and use Unsafe Object to allocate 、 Reclaiming memory .
边栏推荐
- 用tkinter做一个简单图形界面
- Part 7: STM32 serial communication programming
- [hfctf2020]babyupload session parsing engine
- Attention slam: a visual monocular slam that learns from human attention
- 随时随地查看远程试验数据与记录——IPEhub2与IPEmotion APP
- 斗地主游戏的案例开发
- from . cv2 import * ImportError: libGL. so. 1: cannot open shared object file: No such file or direc
- Dell笔记本周期性闪屏故障
- Do you understand this patch of the interface control devaxpress WinForms skin editor?
- UI控件Telerik UI for WinForms新主题——VS2022启发式主题
猜你喜欢
Telerik UI 2022 R2 SP1 Retail-Not Crack
Periodic flash screen failure of Dell notebook
深度学习之环境配置 jupyter notebook
UI控件Telerik UI for WinForms新主题——VS2022启发式主题
Distributed cache
Chapter II proxy and cookies of urllib Library
Make a simple graphical interface with Tkinter
深入探索编译插桩技术(四、ASM 探秘)
Set (generic & list & Set & custom sort)
Part 7: STM32 serial communication programming
随机推荐
pytorch之数据类型tensor
Data processing of deep learning
ZABBIX 5.0: automatically monitor Alibaba cloud RDS through LLD
STM32开发资料链接分享
代码克隆的优缺点
Part 7: STM32 serial communication programming
Deep learning environment configuration jupyter notebook
Data type of pytorch tensor
Informatics Orsay Ibn YBT 1172: find the factorial of n within 10000 | 1.6 14: find the factorial of n within 10000
Come on, don't spread it out. Fashion cloud secretly takes you to collect "cloud" wool, and then secretly builds a personal website to be the king of scrolls, hehe
【批处理DOS-CMD命令-汇总和小结】-跳转、循环、条件命令(goto、errorlevel、if、for[读取、切分、提取字符串]、)cmd命令错误汇总,cmd错误
深度学习简史(二)
Chenglian premium products has completed the first step to enter the international capital market by taking shares in halber international
[batch dos-cmd command - summary and summary] - view or modify file attributes (attrib), view and modify file association types (Assoc, ftype)
再聊聊我常用的15个数据源网站
Trace tool for MySQL further implementation plan
重上吹麻滩——段芝堂创始人翟立冬游记
[Niuke] b-complete square
UI control telerik UI for WinForms new theme - vs2022 heuristic theme
Learning notes 5: ram and ROM