Windows java jvm memory

How to manipulate memory from Java with JNA on Windows

How do I manipulate memory from Java? I know that Java runs in it’s own JVM, so it can’t access process memory directly.

I heard about JNA which can be used to get interfaces between the Operating System and my Java code.

Let’s say I want to manipulate the score of Solitaire. The attempt would be something like this:

  1. get the process of solitaire
  2. get access to the memory of solitaire
  3. find out where the score is stored in the memory
  4. write my new value in the address

Java itself can’t access that memory, so how can I do this using JNA?

2 Answers 2

You need to use the JNA Library. Download the two Jar-Files (jna.jar and jna-platform.jar)

I found a tutorial on pastebin, which explains how to use this Library. But it won’t be necessary to read it to understand the following.

Let’s say, you want to manipulate the addresses and their values of the Windows game «Solitaire»

Know, what you do

If you want to manipulate addresses and their values, know what you do!
You need to know, what size the value, stored in the address, has. Is it 4Byte, or 8Byte or whatsoever.

Know how to use tools to get dynamic and base-addresses. I use CheatEngine.

Know the difference bewteen base-addresses, and dynamic-addresses:

Dynamic-addresses will change every time you restart the application (Solitaire).
They will contain the needed value, but you would need to find the address again every time. So what you need to learn first, is how to get the base-address.
Learn this by playing through the CheatEngine Tutorial.

Base-addresses are static addresses. Those addresses point to other addresses mostly the following way: [[base-addres + offset] + offset] -> value. So what you need is to know the base-address, and the offsets you need to add to the addresses to get the dynamic-address.

So now that you know what you need to know you do some research with the CheatEngine on Solitaire.

You found your dynamic-address and searched for the base-address? Good, let’s share our results:

Base-address for the score: 0x10002AFA8
Offsets to get to the dynamic-address: 0x50 (first) and 0x14 (second)

Got everything right? Good! Let’s continue with actually writing some code.

Create a new Project

In your new project, you need to import those libraries. I use Eclipse, but it should work on any other IDE.

User32 Interface

Thank’s to Todd Fast, for setting up an User32 interface. It’s not complete, but enough we need here.

With this interface, we get access to some functions of the user32.dll on Windows. We need the following functions: FindWindowA and GetWindowThreadProcessID

Side Note: If Eclipse tells you it needs to add unimplemented methods, just ignore it and run the code anyway.

Kernel32 Interface

Thank’s to Deject3d for the Kernel32 interface. I modified it a little bit.

This interface contains the methods we use to read and write to memory. WriteProcessMemory and ReadProcessMemory . It also contains a method to open a process OpenProcess

Actual Manipulation

We now create a new class which will contain some helper methods and the main function as access point for the JVM.

Let’s fill in stuff we already know, like our offsets and the base-address.

Next we use our interfaces to get access to our Windows specific methods:

Last but not least we create some permission constants we need, to get the permission to read and write to a process.

In order to get a process, where we can manipulate the memory, we need to get the window. This window can be used to get the process id. With this id we can open the process.

In the getProcessId method we use the parameter, which is the title of the window, to find the window handle. ( FindWindowA ) This window handle is used to get the process id. An IntByReference is the JNA version of an pointer, where the process id will be stored.

If you get the process id, you can use it to open the process with openProcess . This method gets the permissions and the pid, to open the process, and returns a pointer to it. To read from a process you need the permission PROCESS_VM_READ and to write from a process you need the permissions PROCESS_VM_WRITE and PROCESS_VM_OPERATION.

The next thing we need to get is the actual address. The dynamic-address. So we need another method:

This method needs the process, the offsets and the base-address. It stores some temporary data in a Memory object, which is exactly what it says. A memory. It reads out at the base-address, gets back a new address in the memory and adds the offset. This is done for all offsets and returns in the end the last address, which will be the dynamic-address.

Читайте также:  Темы для линукс минт xfce

So now we want to read our score and print it out. We have the dynamic-addres where the score is stored and just need to read it out. The score is a 4Byte value. Integer is a 4Byte datatype. So we can use an Integer to read it out.

We wrote a wrapper for our kernel32 method readProcessMemory . We know we need to read 4Byte so the bytesToRead will be 4. In the method, a Memory object will be created and returned, which will have the size of byteToRead and store the data, contained in our address. With the .getInt(0) method we can read out the Integer value of our memory at the offset 0.

Play a little bit with your solitaire, and get some points. Then run your code and read out the value. Check if it’s your score.

Our last step will be to manipulate our score. We want to be the best. So we need to write 4Byte data to our memory.

This will be our new score. newScore[0] will be the lowest byte and newScore[3] will be the highest one. So if you wanted to change your score to the value 20 your byte[] would be:
byte[] newScore = new byte[]<0x14,0x00,0x00,0x00>;

Let’s write it in our memory:

With our writeMemory method, we write a byte[] called data to our address. We create a new Memory object and set the size to the length of the array. We write the data to the Memory object with the correct offsets and write the object to our address.

Now you should have the fantastic score of 572662306.

If you don’t know exactly, what some kernel32 or user32 methods do, have a look at MSDN or feel free to ask.

If you don’t get the process id of Solitaire, just check it in your Task Manager and write in the pid manually. The german Solitär won’t work, i think because of the ä in the name.

I hope you liked this tutorial. Most parts are from some other tutorials, but put all together here, so in case someone needs a starting point, this should help.

Thanks again to Deject3d and Todd Fast for their help. If you have issues, just tell me and I try to help you out. If something is missing, feel fre to let me know or add it by yourself.

Thank you and have a nice day.

Let’s have a look at the full code of the SolitaireHack Class:

Как выделить Java больше оперативной памяти

Из-за взаимодействия программного компонента Java с разработанными продуктами могут возникать ошибки, решение которых лежит на плечах пользователя. Оно достигается двумя путями: переустановкой модуля и выделением дополнительной памяти Java. С каждой ситуацией стоит разобраться отдельно.

Зачем увеличивать память Java

Задачу по увеличению Java памяти пользователи ставят перед собой в следующих случаях:

  • Не запускается игра Minecraft. Геймер получает сообщение, что для запуска не хватает виртуальной памяти, хотя минимальные требования по оперативке соблюдены.
  • Проблема с памятью кучи Java. Написанное серверное приложение не запускается. Для его полноценной работы требуется 512 Мб оперативки на компьютере, но трудности с запуском возникают даже при имеющихся 4 Гб.

Исправить проблему можно двумя способами.

Как выделить память Java

Выделить Джава-модулю больше оперативной памяти возможно через «Панель управления». Способ удобнее рассмотреть на примере проблем с запуском игры Minecraft.

Инструкция:

  1. Открывается «Панель управления».
  2. В поиске нужно найти Java-модуль.
  3. После запуска ПО в шапке выбирается раздел Java.
  4. В запустившемся окне открывается View.
  5. Для корректной работы модуля удалите лишние строки, если они есть. Должна остаться только одна, где указана последняя версия ПО. Важно обратить внимание на разрядность.
  6. Для увеличения памяти производится изменение столбца Runtime Parameters. При этом параметры записываются в следующем виде: -Xincgc-Xmx2048M, где 2048 – 2 Гб выделяемой оперативки. Важно писать без пробелов. В 32-битной ОС рекомендуется выделение 768 Мб.
  7. Нажимается ОК, ОС перезагружается.

Расшифровка используемых команд:

  • Xincgc – освобождает неиспользуемые объекты из памяти;
  • Xmx – максимальный объем оперативки;
  • Xms – минимальный объем.

Если это не помогло запустить Minecraft, переустановите модуль Java и игру. После удаления очистите реестр с помощью CCleaner.

Увеличение памяти с помощью переменных среды

Увеличить оперативную память в Джаве можно с помощью переменных системной среды. В виртуальной машине прописываются два аргумента, упомянутых ранее: -Xms и -Xmx.

Чтобы система воспринимала написанные аргументы, нужно добавить переменную с названием «_JAVA_OPTIONS».

Если количество памяти, отведенной для работы Java, в два раза меньше имеющейся оперативки, то команды прописываются по следующей инструкции:

  1. Открываются «Свойства» на ярлыке «Мой компьютер».
  2. Из левой части выбираются «Дополнительные параметры системы».
  3. На вкладке «Дополнительно» производится одиночный клик по «Переменные среды».
  4. Нажимается кнопка «Создать».
  5. Имя переменной: «_JAVA_OPTIONS», аргументы: «-Xms512m -Xmx1024m».

В примере объем оперативки составлял 1 Гб.

Видео: 3 способа выделить больше памяти Java.

Таким образом в статье рассмотрено два метода увеличения оперативной памяти, выделяемой для работы Java-модуля.

How can I increase the JVM memory? [duplicate]

HI, I like to know can I increase the memory of the JVM depending on my application.If yes how can I increase the JVM memory? And how can I know the size of JVM?

Читайте также:  Настройка ассоциаций файлов windows server

4 Answers 4

When starting the JVM, two parameters can be adjusted to suit your memory needs :

specifies the initial Java heap size and

the maximum Java heap size.

If you are using Eclipse then you can do this by specifying the required size for the particular application in its Run Configuration’s VM Arguments as EX: -Xms128m -Xmx512m

Or if you want all applications running from your eclipse to have the same specified size then you can specify this in the eclipse.ini file which is present in your Eclipse home directory.

To get the size of the JVM during Runtime you can use Runtime.totalMemory() which returns the total amount of memory in the Java virtual machine, measured in bytes.

When calling java use the -Xmx Flag for example -Xmx512m for 512 megs for the heap size. You may also want to consider the -xms flag to start the heap larger if you are going to have it grow right from the start. The default size is 128megs.

Right click on project -> Run As -> Run Configurations..-> Select Arguments tab -> In VM Arguments you can increase your JVM memory allocation. Java HotSpot document will help you to setup your VM Argument HERE

I will not prefer to make any changes into eclipse.ini as minor mistake cause lot of issues. It’s easier to play with VM Args

Not the answer you’re looking for? Browse other questions tagged java jvm or ask your own question.

Linked

Hot Network Questions

site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.4.16.39093

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Which arguments stand for what in JVM memory options?

There a lot of JVM arguments that affect the JVM’s memory usage like -Xms, -Xmx, -Xns, -XX:MaxPermSize.

  • What do they do?
  • Are there any more?
  • Which one do I have to increase when I get what error (e.g. OutOfMemoryError , StackOverflowError . )?

I cannot find a good cheat sheet for them — let’s create one here.

4 Answers 4

-Xms: this option sets the initial and minimum Java heap size.

-Xmx: This option sets the maximum Java heap size. The Java heap (the “heap”) is the part of the memory where blocks of memory are allocated to objects and freed during garbage collection.

-XX:PermSize: -XX:MaxPermSize: are used to set size for Permanent Generation. The permanent space is where are stored the class, methods, internalized strings, and similar objects used by the VM and never deallocated (hence the name).

-Xss: sets the thread stack size. Thread stacks are memory areas allocated for each Java thread for their internal use. This is where the thread stores its local execution state.

-Xns: sets the nursery size. the JRockit JVM uses a nursery when the generational garbage collection model is used, that is, when the dynamic garbage collector has determined that the generational garbage collection model should be used or when the static generational concurrent garbage collector ( -Xgc : gencon) has been selected. You can also use -Xns to set a static nursery size when running a dynamic garbage collector (-XgcPrio).

Understanding Java Memory Model

Understanding Java Memory Model is an essential learning for serious Java developers who develop, deploy, monitor, test, and tune performance of a Java application. In this blog post, we are going to discuss on Java memory model and how each part of JVM memory contributes to run our programs.

First of all, check whether you understand the following diagram of JVM architecture. If you are not familiar with it, I highly suggest you to skim through my previous post (“Java Ecosystem (Part 1): Understanding JVM Architecture“) and refresh your knowledge.

JVM Memory Model

You must have used some of the following JVM memory configurations when running resource-intensive Java programs.

  • -XmsSetting — initial Heap size
  • -XmxSetting — maximum Heap size
  • -XX:NewSizeSetting — new generation heap size
  • -XX:MaxNewSizeSetting — maximum New generation heap size
  • -XX:MaxPermGenSetting — maximum size of Permanent generation
  • -XX:SurvivorRatioSetting — new heap size ratios (e.g. if Young Gen size is 10m and memory switch is –XX:SurvivorRatio=2, then 5m will be reserved for Eden space and 2.5m each for both Survivor spaces, default value = 8)
  • -XX:NewRatio — providing ratio of Old/New Gen sizes (default value = 2)

But have you ever wondered how your JVM resides on memory? Let me show it. Just like any other software, JVM consumes the available space on host OS memory.

However, inside JVM, there exist separate memory spaces (Heap, Non-Heap, Cache) in order to store runtime data and compiled code.

1) Heap Memory

  • Heap is divided into 2 parts — Young Generation and Old Generation
  • Heap is allocated when JVM starts up (Initial size: -Xms)
  • Heap size increases/decreases while the application is running
  • Maximum size: -Xmx

1.1) Young Generation

  • This is reserved for containing newly-allocated objects
  • Young Gen includes three parts — Eden Memory and two Survivor Memory spaces (S0, S1)
  • Most of the newly-created objects goes Eden space.
  • When Eden space is filled with objects, Minor GC (a.k.a. Young Collection) is performed and all the survivor objects are moved to one of the survivor spaces.
  • Minor GC also checks the survivor objects and move them to the other survivor space. So at a time, one of the survivor space is always empty.
  • Objects that are survived after many cycles of GC, are moved to the Old generation memory space. Usually it’s done by setting a threshold for the age of the young generation objects before they become eligible to promote to Old generation.
Читайте также:  Python windows 10 для чего нужен

1.2) Old Generation

  • This is reserved for containing long lived objects that could survive after many rounds of Minor GC
  • When Old Gen space is full, Major GC (a.k.a. Old Collection) is performed (usually takes longer time)

2) Non-Heap Memory

  • This includes Permanent Generation (Replaced by Metaspace since Java 8)
  • Perm Gen stores per-class structures such as runtime constant pool, field and method data, and the code for methods and constructors, as well as interned Strings
  • Its size can be changed using -XX:PermSize and -XX:MaxPermSize

3) Cache Memory

  • This includes Code Cache
  • Stores compiled code (i.e. native code) generated by JIT compiler, JVM internal structures, loaded profiler agent code and data, etc.
  • When Code Cache exceeds a threshold, it gets flushed (and objects are not relocated by the GC).

Stack vs. Heap

So far I did not mention anything about Java Stack memory because I wanted to highlight its difference separately. First, take a look at the below image and check whether you know what’s happening here. I have already discussed on JVM Stack in my previous post.

Anyway long story short, Java Stack memory is used for execution of a thread and it contains method specific values and references to other objects in Heap. Let’s put both Stack and Heap into a table and see their differences.

Here’s a nice example (from baeldung.com) on how Stack and Heap contribute to execute a simple program (Check the stack order with the code).

Modifications

The above Java memory model is the most commonly-discussed implementation. However, the latest JVM versions have different modifications such as introducing the following new memory spaces.

  • Keep Area — a new memory space in the Young Generation to contain the most recently allocated objects. No GC is performed until the next Young Generation. This area prevents objects from being promoted just because they were allocated right before a young collection is started.
  • Metaspace — Since Java 8, Permanent Generation is replaced by Metaspace. It can auto increase its size (up to what the underlying OS provides) even though Perm Gen always has a fixed maximum size. As long as the classloader is alive, the metadata remains alive in the Metaspace and can’t be freed.

NOTE: You are always advised to go through the vendor docs to find out what works for your JVM version.

Memory Related Issues

When there is a critical memory issue, the JVM gets crashed and throws an error indication in your program output like below.

  • java.lang.StackOverFlowError — indicates that Stack Memory is full
  • java.lang.OutOfMemoryError: Java heap space — indicates that Heap Memory is full
  • java.lang.OutOfMemoryError: GC Overhead limit exceeded — indicates that GC has reached its overhead limit
  • java.lang.OutOfMemoryError: Permgen space — indicates that Permanent Generation space is full
  • java.lang.OutOfMemoryError: Metaspace — indicates that Metaspace is full (since Java 8)
  • java.lang.OutOfMemoryError: Unable to create new native thread — indicates that JVM native code can no longer create a new native thread from the underlying operating system because so many threads have been already created and they consume all the available memory for the JVM
  • java.lang.OutOfMemoryError: request size bytes for reason — indicates that swap memory space is fully consumed by application
  • java.lang.OutOfMemoryError: Requested array size exceeds VM limit– indicates that our application uses an array size more than the allowed size for the underlying platform

However, what you have to thoroughly understand is that these outputs can only indicate the impact that the JVM had, not the actual error. The actual error and its root cause conditions can occur somewhere in your code (e.g. memory leak, GC issue, synchronization problem), resource allocation, or maybe even hardware setting. Therefore, I can’t advise you to simply increase the affected resource size to solve the problem. Maybe you will need to monitor resource usage, profile each category, go through heap dumps, check and debug/optimize your code etc. And if none of your efforts seems to work and/or your context knowledge indicates that you need more resources, go for it.

What’s Next

During my undergraduate research on JVM performance aspects, we found several approaches used by the industry to minimize the impact of performance faults like memory errors. Let’s discuss about Java Performance Management in-depth very soon. In the meantime, read the next blog post of this series in which I explain how Java Garbage Collection really works under the hood. Stay excited with this blog for more exciting posts!

Оцените статью