当前位置:网站首页>[100 cases of JVM tuning practice] 02 - five cases of virtual machine stack and local method stack tuning
[100 cases of JVM tuning practice] 02 - five cases of virtual machine stack and local method stack tuning
2022-07-02 19:00: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 virtual machine stack and local method stack 、 Teach you to check 5 A common JVM Virtual machine stack case practice
List of articles
3. Virtual machine stack
3.1 Introduction of virtual machine stack
Stack : The memory space required for the thread to run , A stack contains multiple stack frames , Stack frame is the memory required for each method to run , A method call is a stack frame . Stack frame is mainly used to store local variables , Parameters and return address ( The address of the execution method after the method ends ) Of . When a method is called , Method stack frame , When the method execution ends , Corresponding stack frame (Frame) It'll come out of the stack . In addition, each thread can only have one active stack frame , To correspond to the currently executing method .
Use idea You can debug and obtain virtual machine stack information . Lower left corner Frames It corresponds to the virtual machine stack .
reflection
Q1: Does garbage collection involve stack memory
A1: Garbage collection does not involve stack memory , Because the stack frame of the stack will enter the stack with the method call , Out of the stack as the method ends , No garbage collection is required .
Q2: Is the larger the stack memory, the better ?
A2: The stack size can be set .
The larger the thread stack, the more method levels that can be nested , But it needs to be within a reasonable range , Not the bigger the better . Because the physical memory of the computer is limited , The larger the stack size in the thread is set , The fewer threads you can hold ( Each thread has its own stack ). Generally, the default stack memory size of the system can be used .
The following figure shows how to set the stack size .
3.2 Method local variable thread safety problem
Local variables are private variables of the method stack , So is the local variable in the method thread safe ?
Let's start with this example .
// Multiple threads executing at the same time
static void m1() {
int x = 0;
for (int j = 0; j < 500; j++) {
x++;
}
}
The above example will not have thread safety problems . Because each thread has its own stack frame , Storage independent x.
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-0p3I5ZHq-1656678163013)(F:/%E5%8D%9A%E5%AE%A2%E5%9B%BE%E7%89%87/jvm/2.png)]
Take a look at the following example .
static void m2() {
StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("b");
sb.append("c");
}
The answer still won't be safety , The reason is the same as the above example . Then look at the following example .
static void m3(StringBuilder sb ) {
sb = new StringBuilder();
sb.append("a");
sb.append("b");
sb.append("c");
}
The above example is actually thread unsafe . because sb Not thread private .
summary : Method is thread safe ?
- If the local variable in the method does not escape the scope of the method , It's safe .
- If basic data type , It's safe .
- If it is object type data , And escape the scope of the method , The thread is not safe . Reference code demo1, The addresses stored in the variables of different thread stacks will not interfere with each other , But the value of the same address can be modified by different threads .
3.3 Memory overflow of virtual machine stack
The condition that causes stack memory overflow :
- Too many stack frames , For example, the method recurses too many times .
- Stack frame too large , This is rarely the case , Because the default stack frame size is 1M, There is enough storage space .
The following is an example of stack memory overflow .
public class Demo02 {
private static int count;
public static void main(String[] args) {
m1();
}
static void m1() {
count ++;
m1();
}
}
It is worth noting that , Sometimes it's not our own code that causes the memory overflow problem of the stack , But the memory overflow problem is caused by the wrong use of third-party library code .
/** * json Data conversion */
public class Demo03 {
public static void main(String[] args) throws JsonProcessingException {
Dept d = new Dept();
d.setName("Market");
Emp e1 = new Emp();
e1.setName("zhang");
e1.setDept(d);
Emp e2 = new Emp();
e2.setName("li");
e2.setDept(d);
d.setEmps(Arrays.asList(e1, e2));
// { name: 'Market', emps: [{ name:'zhang', dept:{ name:'', emps: [ {}]} },] }
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(d));
}
}
class Emp {
private String name;
@JsonIgnore
private Dept dept;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
}
class Dept {
private String name;
private List<Emp> emps;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Emp> getEmps() {
return emps;
}
public void setEmps(List<Emp> emps) {
this.emps = emps;
}
}
appear Infinite recursion (StackOverflowError)
resolvent : add to @JsonIgnore
annotation .
class Emp {
private String name;
@JsonIgnore
private Dept dept;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
}
3.4 Virtual machine stack cpu Occupation problem
Here are two stack related cases .
Compile and run the following code .
/** * demonstration cpu Occupy too much */
public class Demo04 {
public static void main(String[] args) {
new Thread(null, () -> {
System.out.println("1...");
while(true) {
}
}, "thread1").start();
new Thread(null, () -> {
System.out.println("2...");
try {
Thread.sleep(1000000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "thread2").start();
new Thread(null, () -> {
System.out.println("3...");
try {
Thread.sleep(1000000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "thread3").start();
}
}
linux Next use nohub
Let the process run in the background , Will return directly to the thread id.
nohub java Demo04 &
Use top
To display cpu Occupied by the process ( My environment is windows, Task manager for direct use , I won't repeat it later ).
Locate that the occupancy is too high cpu After the process , Use ps H -eo pid tid %cpu | grep xxx( process id)
To see which thread caused the problem .
Finally using jstack xxx( process id)
View the corresponding of all threads in the process id And the number of source code lines causing problems . Note that the thread number obtained in step 2 is decimal , and jstack The thread number in is 16 Base number , Necessary hexadecimal conversion is required .
32655 The conversion 16 Hexadecimal is 7f99, Therefore, the thread in question is the following thread . Its thread state is runnable, It shows that it has been running , Occupied cpu. And you can also locate the specific number of lines of code according to the stack information .
Corresponding to the source code , We checked out the cause cpu The reason why the occupation is too high .
while(true) {
}
3.5 Thread deadlock troubleshooting
Write the following code .
/** * Demonstrate thread deadlock */
class A{
};
class B{
};
public class Demo05 {
static A a = new A();
static B b = new B();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
synchronized (a) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b) {
System.out.println(" I got it. a and b");
}
}
}).start();
Thread.sleep(1000);
new Thread(()->{
synchronized (b) {
synchronized (a) {
System.out.println(" I got it. a and b");
}
}
}).start();
}
}
linux Next use nohub
Let the process run in the background , Will return directly to the thread id.
windows Can be used directly on java
function , Find the process in the task manager , You can see that id yes 15288.(linux The environment has many development commands , My environment is windows, Combined with the git batsh Use linux Some commands for , I won't repeat it later )
perform jsatck command , You can see the following output
F:\ Information Decrypt JVM\ Code \jvm\src\cn\itcast\jvm\t1\stack>jstack 15288
2022-06-30 20:30:08
Full thread dump Java HotSpot(TM) Client VM (25.301-b09 mixed mode):
...
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x01199894 (object 0x04e9fb40, a A),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0119c1b4 (object 0x04ea0c28, a B),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at Demo05.lambda$main$1(Demo05.java:28)
- waiting to lock <0x04e9fb40> (a A)
- locked <0x04ea0c28> (a B)
at Demo05$$Lambda$2/1503869.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at Demo05.lambda$main$0(Demo05.java:20)
- waiting to lock <0x04ea0c28> (a B)
- locked <0x04e9fb40> (a A)
at Demo05$$Lambda$1/28568555.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
You can clearly see that the deadlock information has been located , stay Demo05.java:28,20 The line has a deadlock . Then go to the code to analyze , Discover threads 1,2 There is an interlock . And this mutual sour information is actually printed out ,Thread-1, Have B wait for A,Thread-2, Have A wait for B.
5. Native Method Stack
Local methods are right and wrong java Language (c/c++) Written directly with the underlying computer operating system API Methods of interaction ,java When the virtual machine calls the local method , Provide memory space for local methods through local method stack .
边栏推荐
- What are the links of the problem
- Google's official response: we have not given up tensorflow and will develop side by side with Jax in the future
- Progress-进度条
- Competence of product manager
- sql训练2
- Web版3D可视化工具,程序员应该知道的97件事,AI前沿论文 | 资讯日报 #2022.07.01
- 彻底搞懂基于Open3D的点云处理教程!
- 一款简约PHP个人发卡程序V4.0版本
- 工业软件讲堂-三维CAD设计软件的核心技术解析----讲坛第二次讲座
- [Yugong series] July 2022 go teaching course 001 introduction to go language premise
猜你喜欢
一款简约PHP个人发卡程序V4.0版本
Redis (7) -- database and expiration key
M2dgr: slam data set of multi-source and multi scene ground robot (ICRA 2022)
夜神模擬器+Fiddler抓包測試App
科技公司不同人对Bug的反应 | 每日趣闻
M2DGR:多源多场景 地面机器人SLAM数据集(ICRA 2022 )
Redis(7)----数据库与过期键
Comprendre complètement le tutoriel de traitement de Point Cloud basé sur open3d!
[daily question] the next day
【每日一题】第一天
随机推荐
UML 类图
promise 和 Observable 的区别
拦截器与过滤器的区别
The text editor hopes to mark the wrong sentences in red, and the text editor uses markdown
Yesterday, Alibaba senior wrote a responsibility chain model, and there were countless bugs
The official docker image running container in version 1.5.1 can be set to use MySQL 8 driver?
故障排查:kubectl报错ValidationError: unknown field \u00a0
iptable端口重定向 MASQUERADE[通俗易懂]
Introduction to sap s/4hana OData mock service
Mysql高级篇学习总结8:InnoDB数据存储结构页的概述、页的内部结构、行格式
Detailed explanation of cjson usage
SQL training 2
2022软件工程期末考试 回忆版
鸿蒙第四次学习
一款简约PHP个人发卡程序V4.0版本
@Component cannot get Dao layer
Have you stepped on the nine common pits in the e-commerce system?
R language dplyr package Na_ The if function converts the control in the vector value into the missing value Na, and converts the specified content into the missing value Na according to the mapping r
Concepts and differences of PR curve and ROC curve
cJSON 使用详解