I have met a memory leak in the following code:
#Override
public void run() {
while (true) {
if(!isRunning) {
break;
}
ThreadHandler handler = threadHandlerRef.get();
if(handler == null) {
break;
}
handler.sendMessage(Message.obtain(handler, 1, this));
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
The memory leak is like below:
In com.****.****:4.2.10:6796.
* com.****.****.SmartConfigMainActivity has leaked:
* GC ROOT com.****.****..NetworkDetector$DThread.<Java Local>
* references android.os.Message.obj
* references com.****.****.$3.a
* references com.****.****.mCommonBindView
* references com.****.****.CommonBindView.mContext
* leaks com.****.****. instance
The thread, as the gc root, holding the local varaiables such as Message. So, the wait() call, from the link:
tells the currently executing thread go to sleep (not use any cpu).
releases the lock so other threads can wake up and take the lock.
Seems wait() also result in holding the local variables. I did not realize this before. Where these local variables? Is it still in the "VM Stack"? Is there more tutorial about this?
=================UPDATE=======================
The SmartConfigMainActivity does not have any relations with the NetworkDetector. I think the Message is re-used in the Looper, which cuased this memory-leak. But I cannot control this re-use behaviour of android.
As I see, jvm should save the local variable to prevent it from gc because when wait() returns, it should come back to the origin state and use these variables. But I did not see any tutorial about this
Related
I have the following piece of code. It has two objects, namely MultiThreadingTest, and the ThreadB object. When we say synchronized(b), what does it mean exactly? Can the 'main' thread get a lock on b before ThreadB finishes it's execution? I can't understand the significance of monitor object in the synchronized block.
package threads;
class MultiThreadingTest
{
public static void main(String[] args)
{
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b)
{
System.out.println("Current thread : "+ Thread.currentThread().getName());
try
{
System.out.println("Waiting for b to complete...");
b.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Total = "+b.total );
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i=0;i<100;i++)
{
total = total + i;
}
notify();
}
}
}
Think of it like the child's game, whoever holds the [whatever object] gets to speak. Whoever holds the monitor object gets to execute in computing terms.
The monitor is the object you are locking upon, at any given time, only one thread accesses code protected by a synchronization block per monitor object. The object itself is arbitrary and doesn't hold much weight onto synchronization (though you have to watch out for reassigning variables as well as null references). Also, JB Nizet raises a good point here on synchronizing on a Thread object since many internal VM methods do that, you can cause bazaar, hard to detect bugs and deadlocks.
Two threads entering different synchronization blocks locking on different monitors will execute concurrently, analogous to two separate groups of people playing/enacting the "who ever holds to xxx gets to speak" game. Locking on this is just a convenient way to manifest a single lock synchronization without creating additional lock objects.
In your case, ThreadB b is the same object pointed to as this from within the ThreadB class meaning that only one thread can enter any of your defined synchronization blocks at once. The order is highly dependent on which thread ran first, the thread scheduler and even the underlying system.
The main reason for monitor objects is so that complex thread-safety mechanisms can be realized. Imagine a system where every synchronization block is single thread access (i.e. at any time, any thread enters a synchronization block will hold every other thread in the whole VM trying to enter a sync block) not only will this cause a massive performance slowdown, it just doesn't make sense. Why should two unrelated application modules lock on each other if they share no data and never interact?
The solution of course is to have one module use one (or several) monitor objects that are unrelated/unassociated with the other module, so both can execute concurrently independent of each other (assuming this is the desired behavior).
To further clarify, you could write:
class MultiThreadingTest{
public static void main(String[] args){
ThreadB b = new ThreadB();
b.setName("Thread B");
b.start();
synchronized(b.lock){
System.out.println("Current thread : "+ Thread.currentThread().getName());
try{
System.out.println("Waiting for b to complete...");
b.lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total = " + b.total );
}
}
}
class ThreadB extends Thread{
public final Object lock = new Object();
int total;
public void run(){
synchronized(lock){
System.out.println("Current thread : "+Thread.currentThread().getName());
for(int i = 0; i < 100; i++){
total = total + i;
}
lock.notify();
}
}
}
to exactly the same effect as the code you've used (even better, since it resolves the conflict with Thread.join() and other methods).
synchronized(this) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by this.
synchronized(b) means that you won't be able to enter this block of code if another thread is inside a block of code that is also synchronized on the object referenced by b.
They thus do the exact same thing. The only difference is the object that is used to lock.
Note that waiting, synchronizing and notifying on an object of type Thread is a really really bad idea. It confuses things, and will lead to unwanted behavior because other methods (join() for example) also use the Thread as a monitor.
As per my understanding, no. The 'this' object within the run() method and the 'b' object in the main() method are the same.
Hence it would not be possible for the 'main' thread to acquire the lock until the thread completes execution.
Also the notify() within the run() method seems to be redundant in this case since its at the end of the method and the lock on the monitor would be relinquished any how.
PS: Do look around for similar questions that may already have been asked in the forum. They may help in providing additional understanding.
all. I have a question for Java wait-notify mechanism. The answer is is there a guaranty that the threads will be executed in this order - from last to the first etc. the result always will be 100, 99, ... , 1 ? This is the snippet of code:
public class Main {
static int counter = 0;
static Object o = new Object();
public static void main(String[] args){
for(int i = 0; i < 100; ++i){
new Thread(() -> {
synchronized (o) {
try {
int c = ++counter;
o.wait();
System.out.println("" + c);
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o) {
new Thread(()-> {
synchronized(o){
System.out.println("LAsttttttttttttttttt");
}
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
o.notifyAll();
}
}
}
I run it 10 times and the result is always the same. I coudn't find anything about this in internet. And one more question - when we have 100 threads waiting, when we notifyAll, is there a guaranty that first one of waiting threads will be executed, after then a second one and after all 100 waiting threads are executed, other waiting methods(which were in synchronized block, but don't have wait() in their body), will be executed after that (after all 100 threads that were waiting are executed). Or notifyAll only guaranty that all waiting threads will start fighting with every method which is synchronized by this object? I thing that this is the answer :
"The awakened threads will not be able to proceed until the current
* thread relinquishes the lock on this object. The awakened threads
* will compete in the usual manner with any other threads that might
* be actively competing to synchronize on this object; for example,
* the awakened threads enjoy no reliable privilege or disadvantage in
* being the next thread to lock this object."
But I want to be sure that I understand what's going on when we have wait-notify.
Thanks in advance.
No . .there is no guarantee that a set of awoken threads will be executed in any particular order. (This may happen in order because of a particular implementation of JVM or the speed of the computer the program is run on, or many other load based variables. However, there is no language guarantee.)
Java's synchronized code block makes no guarantee about the sequence in which threads waiting to enter the synchronized block are allowed to enter, and notifyAll() doesn't present itself as a special case.
As you have seen in notifyAll() javadoc (emphasis mine):
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.
what will the Finalizer thread do if there is a infinite loop or deadlock in the Java finalize method.
The spec writes:
Before the storage for an object is reclaimed by the garbage collector, the Java Virtual Machine will invoke the finalizer of that object.
The Java programming language does not specify how soon a finalizer will be invoked, except to say that it will happen before the storage for the object is reused.
I read this to mean that the finalizer must have completed before the storage may be reused.
The Java programming language does not specify which thread will invoke the finalizer for any given object.
It is important to note that many finalizer threads may be active (this is sometimes needed on large shared memory multiprocessors), and that if a large connected data structure becomes garbage, all of the finalize methods for every object in that data structure could be invoked at the same time, each finalizer invocation running in a different thread.
That is, finalization may occur in the garbage collector thread, in a separate thead, or even a separate thread pool.
A JVM is not permitted to simply abort executing a finalizer, and can only use a finite number of threads (threads are operating system resources, and operating systems don't support arbitrarily many threads). Non-terminating finalizers will therefore of necessity starve that thread pool, thereby inhibit collection of any finalizable objects, and cause a memory leak.
The following test program confirms this behavior:
public class Test {
byte[] memoryHog = new byte[1024 * 1024];
#Override
protected void finalize() throws Throwable {
System.out.println("Finalizing " + this + " in thread " + Thread.currentThread());
for (;;);
}
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new Test();
}
}
}
On Oracle JDK 7, this prints:
Finalizing tools.Test#1f1fba0 in thread Thread[Finalizer,8,system]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at tools.Test.<init>(Test.java:5)
at tools.Test.main(Test.java:15)
I would say that since the Java Specification doesn't tell how the finalize method must be invoked (just that it must be invoked, before the object is garbage collected), the behaviour is implementation specific.
The spec doesn't rule out having multiple threads running the process, but doesn't require it:
It is important to note that many finalizer threads may be active
(this is sometimes needed on large shared memory multiprocessors), and
that if a large connected data structure becomes garbage, all of the
finalize methods for every object in that data structure could be
invoked at the same time, each finalizer invocation running in a
different thread.
Looking at the sources of the JDK7, the FinalizerThread keeps the queue of objects scheduled for finalization (actually objects are added to the queue by the GC, when proven to be unreachable - check ReferenceQueue doc):
private static class FinalizerThread extends Thread {
private volatile boolean running;
FinalizerThread(ThreadGroup g) {
super(g, "Finalizer");
}
public void run() {
if (running)
return;
running = true;
for (;;) {
try {
Finalizer f = (Finalizer)queue.remove();
f.runFinalizer();
} catch (InterruptedException x) {
continue;
}
}
}
}
Each object is removed from the queue, and runFinalizer method is run on it. Check is done if the finalization had run on the object, and if not it is being invoked, as a call to a native method invokeFinalizeMethod. The method simply is calling the finalize method on the object:
JNIEXPORT void JNICALL
Java_java_lang_ref_Finalizer_invokeFinalizeMethod(JNIEnv *env, jclass clazz,
jobject ob)
{
jclass cls;
jmethodID mid;
cls = (*env)->GetObjectClass(env, ob);
if (cls == NULL) return;
mid = (*env)->GetMethodID(env, cls, "finalize", "()V");
if (mid == NULL) return;
(*env)->CallVoidMethod(env, ob, mid);
}
This should lead to a situation, where the objects get queued in the list, while the FinalizerThread is blocked on the faulty object, which in turn should lead to OutOfMemoryError.
So to answer the original question:
what will the Finalizer thread do if there is a infinite loop or deadlock in the Java finalize method.
It will simply sit there and run that infinite loop until OutOfMemoryError.
public class FinalizeLoop {
public static void main(String[] args) {
Thread thread = new Thread() {
#Override
public void run() {
for (;;) {
new FinalizeLoop();
}
}
};
thread.setDaemon(true);
thread.start();
while (true);
}
#Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("Finalize called");
while (true);
}
}
Note the "Finalize called" if printed only once on the JDK6 and JDK7.
The objects will not be "freed", that is the memory will not be claimed back from them and also resources that are freed in the finalize method will remain reserved throughout.
Basically there is a queue holding all the objects waiting for their finalize() method to be executed. Finalizer thread picks up objects from this queue - runs finalize - and releases the object.
If this thread will be deadlocked the ReferenceQueue Queue will grow up and at some point OOM error will become inexorable. Also the resources will be hogged up by the objects in this queue. Hope this helps!!
for(;;)
{
Finalizer f = java.lang.ref.Finalizer.ReferenceQueue.remove();
f.get().finalize();
}
When I create a new object in a thread which is an attribute of an object I´am giving to the thread it stays null in the main-function (but just without the System.out). I wrote a simple example of my Problem, which has the same result:
public class T1 {
public T2 t2;
}
public class T2 {
public String s;
/**
* #param args
*/
public static void main(String[] args) {
T1 t1 = new T1();
T3 thread = new T3(t1);
thread.start();
while(t1.t2 == null){
// System.out.println("null");
}
System.exit(0);
}
}
public class T3 extends Thread{
public T1 t1;
public T3(T1 t1){
this.t1 = t1;
}
#Override
public void run(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t1.t2 = new T2();
while(true){
System.out.println(t1.t2);
}
}
}
So without System.out.println("null") it results in an infinite loop, but when I add this System.out it behaves like I suspect. I even get the same result or problem if I use static variables.
Is there some sort of optimization or something else I don´t understand? Or why is t1.t2 always == null without System.out.println("null")? I thought the T1-object and his attributes (in this case the object t2) will be created on the heap, which is shared between all threads and just the t1-reference-variable is stored on the stack. So hopefully someone can explain me, why it stays null without the System.out... The problem just occurs if the thread is executed after the while-loop, thats why there is a sleep(1000).
So without System.out.println("null") it results in an infinite loop, but when I add this System.out it behaves like I suspect. I even get the same result or problem if I use static variables.
If a thread is updating a value that another thread is reading, there must be some sort of memory synchronization. When you add the System.out.println(...) this uses the underlying PrintStream which is a synchronized class. So the call to println(...) is what synchronizes the memory between the threads.
Here's some good information around memory synchronization from Oracle.
You should add volatile to the T2 t2; field to have the updates to t2 be visible between threads.
The real problem here is that with a modern multi-CPU (and core) hardware, each CPU has its own high speed memory caches. Modern OS and JVM software makes use of these physical (and virtual) CPUs to schedule threads to run in parallel simultaneously. These caches are a critical part of threading performance. If every read and every write had to go to central storage, your application would run 2+ times order of magnitude slower. The memory synchronization flushes the cache so that local writes getting written to central storage, and local cached reads are marked dirty so they have to be re-read from central storage when necessary.
I have a java applet. A class inside that applet is creating a thread to do some work, waiting 30 seconds for that work to complete, if its not completed in 30 secs it sets a Boolean to stop the thread. The wait and Boolean change are in a synchronized block, Is this necessary considering there is no other thread running aside from these 2.
System.out.println("Begin Start Session");
_sessionThread = new SessionThread();
_sessionThread.start();
synchronized (_sessionThread)
{
_sessionThread.wait(30000);
_sessionThread._stopStartSession = true;
}
Why couldn't I just do this instead.
System.out.println("Begin Start Session");
_sessionThread = new SessionThread();
_sessionThread.start();
_sessionThread.wait(30000);
_sessionThread._stopStartSession = true;
SessionThread run method. Invokes a JNI method to call a dll to open a program window.
public void run()
{
try
{
startExtraSession();
}
catch (Throwable t)
{
t.printStackTrace();
}
notify();
}
private native void openSessionWindow(String session_file);
private void startExtraSession()
{
final String method_name = "startExtraSession";
String title = _sessionInfo._title;
long hwnd = 0;
openSessionWindow(_sessionInfo._configFile);
try
{
//Look for a window with the predefined title name...
while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession)
{
Thread.sleep(500);
}
}
catch(Throwable t)
{
t.printStackTrace();
}
}
1. Is the synchronized really needed?
2. Is there a better way to accomplish this aside from using threads?
A given thread is required to own a lock on a object to be able to call wait(long) on it. This is achieved by using a synchronized block on the said object.
See J2SE specification on using wait.
Acquiring a lock/monitor in java can be done in various ways:
In a synchronized (non-static) method, the thread owns a monitor on the object referenced by this.
In a static synchronized method, the thread owns a monitor on the Class<?> descriptor for the class that defines the said method.
In a synchronized(x) block, the thread owns a monitor on x.
That lock will be released if:
You get outside of the synchronized code block (be it a method, static method, or explicit block).
You have called wait() or one of its variations (and you'll re-acquire it just before the method returns).
Both these two lists may omit specific cases but should cover at least a large portion of the typical use cases.
There's a very simple reason that you need synchronized to call wait
The synchronized makes sure that nobody is calling notify or notifyAll at the same time you're calling wait
For example: Thread 1
synchronized( obj )
{
triggerActionOnThread2();
obj.wait();
}
Thread 2 (triggered by triggerActionOnThread2)
...
synchronized( obj )
{
obj.notify();
}
If you don't have the synchronized blocks, then the notify might happen before (or during) the wait, and then the wait misses the notify, and you can hang Thread 1.
Imagine the above blocks of code without the synchronized blocks, and imagine if Thread 2 is executed all the way through the notify before the wait gets called.
BTW, I ask this very question on interviews for Java engineers when the job will involve multithreaded programming.
Can you please post SessionThread code? You cannot wait if you don't own the lock, so you need synchronized (_sessionThread) to do _sessionThread.wait(30000); Not sure what's with _sessionThread._stopStartSession = true;
If the boolean is the only shared state between the threads, declaring the boolean transient will guarantee that changes to it are seen between the threads as would a synchronization block around access to the boolean.