当前位置:网站首页>[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 .
边栏推荐
- Tencent cloud webshell experience
- Installation and testing of pyflink
- ARM裸板调试之JTAG原理
- Part V: STM32 system timer and general timer programming
- 【JVM调优实战100例】05——方法区调优实战(下)
- 【JokerのZYNQ7020】AXI_ EMC。
- 重上吹麻滩——段芝堂创始人翟立冬游记
- 筑梦数字时代,城链科技战略峰会西安站顺利落幕
- 界面控件DevExpress WinForms皮肤编辑器的这个补丁,你了解了吗?
- How to get started and improve test development?
猜你喜欢

深度学习之环境配置 jupyter notebook

重上吹麻滩——段芝堂创始人翟立冬游记

Activereportsjs 3.1 Chinese version | | | activereportsjs 3.1 English version

ActiveReportsJS 3.1中文版|||ActiveReportsJS 3.1英文版

Build your own website (17)

Attention slam: a visual monocular slam that learns from human attention

Chapter II proxy and cookies of urllib Library

Configuring the stub area of OSPF for Huawei devices

Telerik UI 2022 R2 SP1 Retail-Not Crack

第四篇,STM32中断控制编程
随机推荐
Deep learning framework TF installation
Anfulai embedded weekly report no. 272: 2022.06.27--2022.07.03
pyflink的安装和测试
[software reverse - solve flag] memory acquisition, inverse transformation operation, linear transformation, constraint solving
Learn self 3D representation like ray tracing ego3rt
How to get started and improve test development?
[batch dos-cmd command - summary and summary] - jump, cycle, condition commands (goto, errorlevel, if, for [read, segment, extract string]), CMD command error summary, CMD error
通过串口实现printf函数,中断实现串口数据接收
深度学习之环境配置 jupyter notebook
. Bytecode structure of class file
Part IV: STM32 interrupt control programming
Chapter II proxy and cookies of urllib Library
深度学习简史(一)
Data type of pytorch tensor
UI control telerik UI for WinForms new theme - vs2022 heuristic theme
代码克隆的优缺点
[牛客] [NOIP2015]跳石头
[hfctf2020]babyupload session parsing engine
深度学习之线性代数
第六篇,STM32脉冲宽度调制(PWM)编程