当前位置:网站首页>[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 .
边栏推荐
- Configuring OSPF basic functions for Huawei devices
- C9高校,博士生一作发Nature!
- A brief history of deep learning (II)
- mysql: error while loading shared libraries: libtinfo. so. 5: cannot open shared object file: No such
- Tencent cloud webshell experience
- Address information parsing in one line of code
- 【JokerのZYNQ7020】AXI_ EMC。
- from .cv2 import * ImportError: libGL.so.1: cannot open shared object file: No such file or direc
- Lombok makes ⽤ @data and @builder's pit at the same time. Are you hit?
- 再聊聊我常用的15个数据源网站
猜你喜欢
Chapter II proxy and cookies of urllib Library
Part VI, STM32 pulse width modulation (PWM) programming
[Niuke] [noip2015] jumping stone
深度学习之线性代数
Trace tool for MySQL further implementation plan
View remote test data and records anytime, anywhere -- ipehub2 and ipemotion app
Windows installation mysql8 (5 minutes)
C9高校,博士生一作发Nature!
【批處理DOS-CMD命令-匯總和小結】-字符串搜索、查找、篩選命令(find、findstr),Find和findstr的區別和辨析
ARM裸板调试之JTAG原理
随机推荐
Data type of pytorch tensor
【批处理DOS-CMD命令-汇总和小结】-查看或修改文件属性(ATTRIB),查看、修改文件关联类型(assoc、ftype)
Data sharing of the 835 postgraduate entrance examination of software engineering in Hainan University in 23
.class文件的字节码结构
建立自己的网站(17)
Chapter 5 DML data operation
Tencent cloud webshell experience
pyflink的安装和测试
mongodb客户端操作(MongoRepository)
UI control telerik UI for WinForms new theme - vs2022 heuristic theme
筑梦数字时代,城链科技战略峰会西安站顺利落幕
Telerik UI 2022 R2 SP1 Retail-Not Crack
Attention SLAM:一种从人类注意中学习的视觉单目SLAM
代码克隆的优缺点
[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
String comparison in batch file - string comparison in batch file
Configuring the stub area of OSPF for Huawei devices
实现mysql与ES的增量数据同步
学习光线跟踪一样的自3D表征Ego3RT
深度学习框架TF安装