java - Why JVM does not support forced class/classloader unloading? -


disclaimer: know how classes loaded in jvm , how , when unloaded. question not current behaviour, question is, why jvm not support "forced" class/classloader unloading?

it have following semantics: when classloader "forced unloaded", classes loaded marked "unloaded", meaning no new instances created (an exception thrown, "classunloadedexception"). then, instances of such unloaded classes marked "unloaded" too, every access them throw instanceunloadedexception (just nullpointerexception).

implementation: think, done during garbage collection. example, compacting collector moves live objects anyway, can check if class of current object "unloaded" , instead of moving object change reference guarded page of memory (accessing throw abovementioned instanceunloadedexception). make object garbage, too. or done during "mark" phase of gc. anyway, think technically possible, little overhead when no "unloading" occurs.

the rationale: such "hardcore" mechanism useful runtimes lot of dynamic code reloading occurs , failure of particular application or part of tolerable whereas failure of whole jvm undesirable. example, application servers , osgi runtimes.

in experience, dynamic redeployment in 9 cases of 10 leads permgenspace due references not being cleaned correctly (like threadlocal in static field filled in long-living thread, etc). also, having explicit exception instead of hard-to-debug leak polishing code no references leaked long-living scope uncontrolled.

what think?

this feature cause havoc , confusion. forcing unload of class bring lot of problems, deprecated thread.stop() had, except many more times worse.

just comparing, thread.stop() tends leave lot of objects in inconsistent states due abrupt thread interrupting, , thread executing type of code. coding against in practice impossible, or @ least tremendous extreme effort. considered between impossible , impossible write correct multithreded code in scenario.

in case, sort of feature have similar bad side-effects, in worse scale. code exception anywhere unexpectedly, in practice difficult or impossible code defensively against or handle it. suppose have try block doing io, , class abruptely unloaded. code throw classunloadedexception in unexpected place, potentially leaving objects in inconsistent states. if try defend code against it, code responsible defense might fail due unexpected classunloadedexception. if have block tries close resource , classunloadedexception thrown inside block, resource not closed. , again, handling hard, because handler classunloadedexception too.

by way, nullpointerexception predictable. got pointer null , tried derefence it. programming error, behaviour completelly predictable. classcastexception, illegalstateexception, illegalargumentexception , other runtimeexceptions (or @ least should be) happening in predictable conditions. exceptions not runtimeexception may happen unexpectedly (like ioexception), compiler forces handle or rethrow them.

on other hand, stackoverflowerror, outofmemoryerror, exceptionininitializererror , noclassdeffounderror, unpredictable things may happen anywhere in code , there possible handle or recover them. when program hits that, go erratic crazy. few ones try handle them, limits warning user must terminated immediatelly, maybe trying save unsaved data. classunloadedexception typical thing classunloadederror instead. manifest exceptionininitializererror or noclassdeffounderror in 99% of cases means application broken, except worse because has not fail-fast behaviour, , gets still more randomness , unpredictableness it.

dynamic redeployment nature, 1 of ugly hacks may happens in jvm/container since changes abruptely code of running on it, tends erratic random buggy behavior. has value, since helps lot in debugging. so, defense against erratic behavior container implements, create new set of classes running program , shares memory older one. if new , old parts of program don't communicate directly (i.e., compatible serialization or no communication @ all), fine. safe if no structural changes occurs , no living object depends of specific implementation detail changed. if follow these rules, no classunloadederror show. there situations may not follow these rules , still safe, fixing bug in method , changing parameters , no live object exists depends on bug (i.e., never existed or dead).

but if wants classunloadederror being thrown if object of older part accessed, behaviour flags 1 of isolament rules broke, , bring down. so, there no point in have new , old parts of program in same time, simpler redeploy completely.

and implementation in gc, not works. dead object dead, no matter if class object dead or alive. living objects of unloaded classes can't garbage collected, because still reachable other objects, no matter if implementation of every method magically change throws exception/error. backtracking references object expensive operation in implementation, , multithreading still worse, possibly severe performance hit in living objects , classes.

further, dynamic loading classes not intended production use, developer tests. so, no worth buy trouble , complexity feature.

concluding, in practice idea creates combines similar thread.stop() similar noclassdeffounderror, stronger sum of two. queen combination of bishop , rook in chess, stronger sum of two. bad idea.


Comments

Popular posts from this blog

java - SNMP4J General Variable Binding Error -

sql server - python to mssql encoding problem -

windows - Python Service Installation - "Could not find PythonClass entry" -