Run Java Threads On One CPU - java

We Have a Multi-threaded Application in JAVA which has multiple threads running in parallel. Now we want to run all these threads on a single core. Currently application is running on a system having more then one Cores.
We know there is a technique available ProcesAffinity in .Net Framework to set process affinity.
But we don't want to depend on .Net Framework, because our application is build in java.
Do we set Process affinity using Bat file and run our application executable jar file through Bat file?
Currently our application is running on Window XP. So we need a solution that should be working fine on XP platform.

EDIT:
It's possible: See Java thread affinity
Pure Java doesn't support running a thread on specific processor. Check the SO question linked above.

Personally, I don't think that the fact that this cannot be set in pure Java is a bad thing, as to me, how an app is run does very much depend on the OS, so therefore a OS-specific solution isn't a bad thing.
You can use the MS psexec utility to set the affinity:
psexec -a 1 java -jar myapplication.jar
Would instruct that all of the threads created by java would be run on the lowest CPU.
And this line would be your .BAT file...

You cannot do it in pure Java. But on some versions of Windows, you can do it via operating system utilities; see https://superuser.com/questions/309617/how-to-limit-a-process-to-a-single-cpu-core ... and you might be able to do this by calling native libraries via JNI.

Related

Find and kill a specific Java process from another Java App

I have several java processes running on a windows machine. I have a Java process which is supposed to monitor the other processes and periodically kill or restart new ones.
If I have a java process running com.foo.Main1 and one running com.foo.Main2 - how can my monitoring process find and kill just the Main2 process?
Update: I have some code that can execute a command line tasklist.exe and parse it, but no matter what I do, I only see the java.exe process, not which class is executing
Update 2: I do not have the ability to install non-java programs.
It's probably going to be a lot simpler using OS-specific tools and using Runtime.exec() to run them, but I'll try and give a platform independent answer:
It might be possible to do this platform independently using the Attach API. This comes with the JDK, so to use it just include tools.jar from your JDK on your program's classpath.
To get a list of virtual machines on the system, use VirtualMachine.list(). You can get/parse arguments from the virtual machine descriptor objects that are returned from this.
The attach API also allows you to load agents into already-running Java processes. Since you want to kill a Java process, you can write a Java agent that simply runs System.exit() (or if you really want it dead use Runtime.halt() instead) when the agent loads.
Once you identify the one you want to kill, attach to it and load the killer agent (the agent has to be built as a JAR file, accessible to the Java process it needs to be loaded into). Shortly after the agent is attached that process should die.
These links might help also:
An Oracle blog on the attach API
Package documentation for java.lang.instrument (has detailed instructions on how to build an agent JAR)
This is specific to Windows.
I was facing the same issue where I have to kill the specific java program using taskkill. When I run the java program, tasklist was showing the same program with Image name set as java.exe. But killing it using taskkill /F java.exe will stop all other java applications other than intended one which is not required.
So I run the same java program using:
start "MyProgramName" java java-program..
Here start command will open a new window and run the java program with window's title set to MyProgramName.
Now to kil this java-program use the following taskkill command:
taskkill /fi "MyProgramName"
Your Java program will be killed only. Rest will be unaffected.

run separate background process on java web server

Basically I want to use a jsp web page, so in Java, to run(manager) different background process (could be anything that runs) on a linux server.
They need to be run as different user than the web itself.
I wonder what options do I have?
I just found out that
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("linux command");
may work.
But I don't know whether the (child?) process just started will be completely detached from the java servlet process? And is it possible to run it under different account?
Using Runtime in a supposedly lifelong running Java EE web application is a bad idea.
First and foremost, a new process created by Runtime will by design allocate as many new heap memory as the currently running Java environment. This may not necessarily harm inside a simple Java application which uses by default 64MB or something, but in a Java EE web application which ususually allocates memory in terms of gigabytes, this is going to be a complete memory waste.
Second, you just don't want so spawn unmanaged processes/threads inside a Java EE web application. What if the process/thread stalls and/or runs forever which can cause unability to shutdown/restart the Java EE web application when necessary (you'd need to kill it altogether first)? What if the process crashes and takes down your whole Java EE runtime along it?
Last, you cannot change the user running the process. It will always be the same user who has executed the currently running Java runtime.
You have basically 2 options:
Don't use Java for this at all. For example, just do the job using platform provided background job manager, such as Cron in Unix based platforms and Task Scheduler in Windows based platforms.
Do it in 100% Java. Perform the same goal using pure Java, without the need to spawn a process. You can if necessary manage background jobs using ExecutorService API or a 3rd party library like Quartz. Note that even those jobs have still to run 100% pure Java code.

linux top show java threads?

In a linux server(fedora), we run a single JBOSS Application Server, and we use quartz to schedule our task.
Yesterday,
I use a top command to view process status
see more than one processes named Java with different pid are displayed.
But if i use ps aux|grep java only one java process(Jboss AS) is displayed?
So my question would be:
Is a java thread mapped to native linux thread(cloned process), or does top not show threads?
Env:
Kernerl: 2.6.18
JDK: 1.6.0-23
It depends on your versions of various tools. Most likely, you have a version of top that doesn't understand the relationship between threads and processes on Linux, resulting in it incorrectly showing each thread as its own process. The implementation of Java threads depends on your VM, but the typical implementation on modern JVMs and Linux versions is 1-to-1, that is, each Java thread is a Linux KSE created by the clone system call.
If you have a Linux distribution that came out within the past three years, you shouldn't have this issue.

Are there any Java libraries for adjusting IO scheduler priority on linux

I have a Java program running on a linux system, which I would like to give a higher IO Scheduler priority. Is there a library JNI/JNA based that would allow me to do that from within my code?
You could spawn and external command and call ionice on your process.
You can get the PID of the Java Process by using the Java Management API, at least when using the Sun JVM. Have a look at the actual implementations of the management objects, one returns the pid (don't know which for the moment).
Then I would use jnative to call the linux function, so you don't have to rely on ionice to be installed.

How can I give my Java application a unique process name?

I've noticed that when I start Netbeans it shows up in the task manager as netbeans.exe as all my own Java applications show up as java.exe or javaw.exe.
How can I change that so my process names shows up as myapp.exe?
The process name is the name of the JVM. So if you rename the jvm you have an other process name. There are some tools which can do that for you. For example Launch4J
IMO the best option is to choose one of the many open source launchers. They all provide a nicer deployment container than java.exe and a batch file.
I've compiled a list of them after a brief search on google (in no particular order and may not be exhaustive):
NSIS
Janel (dead link)
JSmooth
Launch4J
WinRun4J
(full disclosure: i work on winrun4j)
Not easily. The easiest way (but not nice!) would be to simply copy the java.exe (only 68k on my system, so perhaps practical!)
If you're worried about identifying which java process is which (e.g. is one consuming memory/CPU etc.), use the standard tool jps to identify the Java processes
Netbeans and Eclipse both ship with an .exe file that in turns launches a JVM. The exe itaself probably does nothing after launching the VM. You see the NetBeans javaw.exe in the Task Manager also, I suspect.
So you'll need to write a native exe (using some windows tool) that does a similar thing.
Just answered this a second ago here: Get JVM to grow memory demand as needed up to size of VM limit?
It's actually a lot easier than folks are saying (but you do have to have a c/c++ compiler handy).
There are mainly 2 approaches: one is as already described: using tools like Launch4j, WinRun4J to create native Windows launchers.
Another approach that seems better is to use Apache Procrun to wrap the java application as a Windows service. During the install service process, we can give the process an meaningful name such as OurApp.exe.
All we need do is rename prunsrv.exe to OurApp.exe and replace every occurrence of prunsrv.exe in our install|start|stop|uninstall service scripts to MyApp.exe.
See more from Using Apache Procrun to Rename Process Name of a Java Program in Windows

Categories

Resources