Java Performance Tuning
Java(TM) - see bottom of page
Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks!
Training online: Concurrency, Threading, GC, Advanced Java and more ...
Tips January 2022
JProfiler
|
Get rid of your performance problems and memory leaks!
|
JProfiler
|
Get rid of your performance problems and memory leaks!
|
|
|
Back to newsletter 254 contents
https://www.youtube.com/watch?v=o9NVLXKRKeY
The definitive guide to Java agents (Page last updated January 2022, Added 2022-01-28, Author Rafael Winterhalter, Publisher Devoxx). Tips:
- The JVM has 3 entry points: agentmain, premain, main. -javaagent uses premain, which also runs on the main thread, and you can have multiple java agents. The agentmain is on it's own thread and if you attach to a JVM you enter this thread. You can have multiple agents but there is only one entry thread.
- Java agents are often injected using VirtualMachine.attach(PID).loadAgent(JAR_PATH,AGENTNAME) and this will attach to the target JVM (running with process ID PID) on the agentmain thread, calling the agentmain() method specified in the target class in the jar in JAR_PATH.
- The second argument in the premain() and agentmain() method is a Instrumentation instance which allows the agent to transform classes - adding and deleting bytecode to classes - both for already loaded classes, and newly loading classes.
- ByteBuddy provides a higher level Java pattern interface to transform classes than the low level provided by Instrumentation. Most popular agents are using ByteBuddy, and most of these use the ByteBuddy Advice pattern.
- Self attachment of agents has been explicitly disallowed since JDK9, so if you want to do that, you need to spawn a child JVM and attach the agent to the parent JVM.
- If you add an agent, the agents will affect some object lifecycles, and that can easily affect the GC behaviour.
https://www.elastic.co/blog/embracing-invokedynamic-to-tame-class-loaders-in-java-agents
Embracing invokedynamic to tame class loaders in Java agents (Page last updated November 2021, Added 2022-01-28, Author Felix Barnsteiner, Rafael Winterhalter, Publisher Elastic). Tips:
- ByteBuddy let's you inline code into methods AFTER (or while) they've been loaded into the JVM. This let's you easily add timing around specific methods.
- A new technique of using dedicated classloaders and helper classes, instead of inlining code, allows for more flexibility and better encapsulation of agent instrumented code. A single bootstrap class needs to be dynamically injected to java.lang, and ByteBuddy is able to inject dynamic calls to helper classes which makes instrumenting methods very modular - and additionally allows for full reversal and detachment of all the injected code and objects allowing for complete agent removal.
https://www.youtube.com/watch?v=wgJWs14YcEs
An Introduction to JVM Performance (Page last updated May 2020, Added 2022-01-28, Author Rafael Winterhalter, Publisher GOTO). Tips:
- JVM bytecode is initially run interpreted, but any code that is being used is profiled and quickly JIT compiled.
- If your method is monomorphic or bimorphic, it is much more efficient than otherwise, code is reached quicker and can be inlined. This means that for optimal performance only one or two classes should implement a particular method in a particular hierarchy under the particular target type, eg For a List variable, if you are only using one or two implementations (say ArrayList and LinkedList), the code can be optimized much better than if you can assign 3 or more List implementations to that variable - ie the application only loads one or two List implementations during the JVM lifetime.
- For megamorphic calls, you can micro-optimize by converting to a method which explicitly switches to execute one of the statically defined methods. This is bad programming practice but may be a useful technique for certain types of applications that need to have tight control on how calls are made.
- Processors work speculatively, so if it can correctly predict the outcome of a branch, it will be faster. Consequently moving from random to ordered data used in branches (if statements), can speed up things.
- Minimizing the scope of your objects gives the highest chance for escape analysis to be applied and avoid creating objects in the heap, creating them on the stack instead, which avoids the GC overhead of the object.
Jack Shirazi
Back to newsletter 254 contents
Last Updated: 2024-11-29
Copyright © 2000-2024 Fasterj.com. All Rights Reserved.
All trademarks and registered trademarks appearing on JavaPerformanceTuning.com are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. JavaPerformanceTuning.com is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
URL: http://www.JavaPerformanceTuning.com/news/newtips254.shtml
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us