0% found this document useful (0 votes)
21 views12 pages

Unit-4 PPL

Uploaded by

Roushan Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views12 pages

Unit-4 PPL

Uploaded by

Roushan Kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

PPL Unit-4

 Abstract Data type (ADTs):


ADTs are like user defined data types which defines operations on value using function without
specifying what is there inside the function and operations are performed.
Think of ADT as a black box which hides the inner structure and design of data type from the user.

An abstract data type is an abstraction of a data structure that provides only the interface to which
the data structure must adhere. The interface does not give any specific details about something
should be implemented or in what programming language.

 Abstract data type model


Before knowing about the abstract data type model, we should know about abstraction and
encapsulation.
Abstraction: It is a technique of hiding the internal details from the user and only showing the
necessary details to the user.
Encapsulation: It is a technique of combining the data and the member function in a single unit is
known as encapsulation.

T he above figure shows the ADT model. There are two types of models in the ADT model, i.e., the
public function and the private function. The ADT model also contains the data structures that we
are using in a program. In this model, first encapsulation is performed, i.e., all the data is wrapped in
a single unit, i.e., ADT. Then, the abstraction is performed means showing the operations that can be
performed on the data structure and what are the data structures that we are using in a program.

 Types of ADT
ADTs allow users to effectively implement complex mathematical
and logical programs as they are flexible and independent of
language. There are three types of ADTs.
1. List
2. Queue
3. Stack

1. List: The list ADT is a sequential combination of one or more than one element. Each
element has its positional value and a referential pointer to the next element. Users can't
access elements randomly, so the head pointer is initialized to the first element of the list.
Basic operations of the list are as follows:

1
PPL Unit-4

2. Queue: The queue is a linear ADT which allows insertion from one end and deletion from
another. As per the name, It works on the FIFO (first in, first out) principle. The queue has
two ends, front and rear. The rear end is used for insertion, and the front end is used for
deletion.
The basic operations of the queue are as follows:

3. Stack: A stack is a linear ADT that restricts users from inserting and deleting elements from
only one end, known as the top of the stack. It uses LIFO (last in, first out) as its basic
working principle. The top of the queue always has a recently inserted element.
Basic operations of the stack are as follows:

 OOPs Concepts
Object-Oriented Programming is a methodology or paradigm to design a program using classes and
objects.

 Features of OOPs
1. Object: Any entity that has state and behavior is
known as an object. An Object can be defined as an
instance of a class. An object contains an address and
takes up some space in memory.

An object has three characteristics:


i. State: represents the data (value) of an object.
ii. Behavior: represents the behavior (functionality)
of an object such as deposit, withdraw, etc.
iii. Identity: An object identity is typically
implemented via a unique ID. The value of the ID
is not visible to the external user. However, it is
used internally by the JVM to identify each object
uniquely.
2. Class: Collection of objects is called class. It is a logical entity. A class can also be defined as a
blueprint from which you can create an individual object. Class doesn't consume any space.

A class in Java can contain:


i. Fields
ii. Methods
iii. Constructors
iv. Blocks
v. Nested class and interface

2
PPL Unit-4

3. Inheritance: When one object acquires all the properties and behaviours of a parent object, it is
known as inheritance. It provides code reusability. It is used to achieve runtime polymorphism.

The idea behind inheritance in Java is that you can create new classes that are built upon existing
classes. When you inherit from an existing class, you can reuse methods and fields of the parent
class. Moreover, you can add new methods and fields in your current class also.

Inheritance represents the IS-A relationship which is also known as a parent-child relationship.

Terms used in Inheritance

 Class: A class is a group of objects which have common properties. It is a template or


blueprint from which objects are created.
 Sub Class/Child Class: Subclass is a class which inherits the other class. It is also called a
derived class, extended class, or child class.
 Super Class/Parent Class: Superclass is the class from where a subclass inherits the features.
It is also called a base class or a parent class.
 Reusability: As the name specifies, reusability is a mechanism which facilitates you to reuse
the fields and methods of the existing class when you create a new class. You can use the
same fields and methods already defined in the previous class.

The extends keyword indicates that you are making a new class that derives from an existing class.
The meaning of "extends" is to increase the functionality.

 Types of inheritance in java


i. Single Inheritance: When a class inherits another class, it is known as a single
inheritance. In the example given below, Dog class inherits the Animal class, so there is
the single inheritance.
Example: class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void bark(){System.out.println("barking...");}
}
class TestInheritance{ output:
public static void main(String args[]){ barking...
Dog d=new Dog(); eating...
d.bark();
d.eat();
}}

ii. Multilevel Inheritance: When there is a chain of inheritance, it is known as multilevel


inheritance. As you can see in the example given below, BabyDog class inherits the Dog
class which again inherits the Animal class, so there is a multilevel inheritance.
Example: class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void bark(){System.out.println("barking...");}
}
class BabyDog extends Dog{
void weep(){System.out.println("weeping...");}
}
class TestInheritance2{
public static void main(String args[]){
3
PPL Unit-4

BabyDog d=new BabyDog();


d.weep();
d.bark();
d.eat();
}}

iii. Hierarchical Inheritance: When two or more classes inherits a single class, it is
known as hierarchical inheritance. In the example given below, Dog and Cat
classes inherits the Animal class, so there is hierarchical inheritance.
Example: class Animal{
void eat(){System.out.println("eating...");}
}
class Dog extends Animal{
void bark(){System.out.println("barking...");}
}
class Cat extends Animal{
void meow(){System.out.println("meowing...");}
}
class TestInheritance3{
public static void main(String args[]){
Cat c=new Cat();
c.meow();
c.eat();
//c.bark();//C.T.Error
}}

iv. Multiple Inheritance: Multiple inheritance is a feature of some object-oriented


computer programming languages in which an object or class can inherit features
from more than one parent object or parent class.

v. Hybrid inheritance: The process of combining more than one type of Inheritance together while
deriving subclasses in a program is called a Hybrid Inheritance.

4. Abstraction or Information Hiding: Abstraction is a process of hiding the implementation


details and showing only functionality to the user.

Another way, it shows only essential things to the user and hides the internal details, for example,
sending SMS where you type the text and send the message. You don't know the internal processing
about the message delivery.

Ways to achieve Abstraction


There are two ways to achieve abstraction in java

4
PPL Unit-4

i. Abstract class: A class which is declared as abstract is known as an abstract class. It can have
abstract and non-abstract methods. It needs to be extended and its method implemented. It
cannot be instantiated.
Point to be remembered
 An abstract class must be declared with an abstract keyword.
 It can have abstract and non-abstract methods.
 It cannot be instantiated.
 It can have constructors and static methods also.
 It can have final methods which will force the subclass not to change the body of the
method.
Syntax: abstract class A{}

Abstract Method: A method which is declared as abstract and does not have implementation is
known as an abstract method.
Example:
abstract class Bike{
abstract void run();
}
class Honda4 extends Bike{
void run(){System.out.println("running safely");} output:
public static void main(String args[]){
Bike obj = new Honda4();
obj.run();
}
}

ii. Interface:
 An interface in Java is a blueprint of a class. It has static constants and abstract methods.
 The interface in Java is a mechanism to achieve abstraction. There can be only abstract
methods in the Java interface, not method body. It is used to achieve abstraction and
multiple inheritance in Java.
 In other words, you can say that interfaces can have abstract methods and variables. It
cannot have a method body.
 Java Interface also represents the IS-A relationship.
 It cannot be instantiated just like the abstract class.
 An interface is declared by using the interface keyword.
Example:
interface printable{
void print();
}
class A6 implements printable{
public void print(){System.out.println("Hello");}
public static void main(String args[]){
A6 obj = new A6();
obj.print();
}
}

5. Encapsulation: Encapsulation in Java is a process of wrapping code and data together into a
single unit, for example, a capsule which is mixed of several medicines.
We can create a fully encapsulated class in Java by making all the data members of the class private.
Now we can use setter and getter methods to set and get the data in it.
5
PPL Unit-4

The Java Bean class is the example of a fully encapsulated class.


Advantage of Encapsulation in Java
 By providing only a setter or getter method, you can make the class read-only or write-only.
In other words, you can skip the getter or setter methods.
 It provides you the control over the data.
 It is a way to achieve data hiding in Java because other class will not be able to access the
data through the private data members.
 The encapsulate class is easy to test. So, it is better for unit testing.
 The standard IDE's are providing the facility to generate the getters and setters. So, it is easy
and fast to create an encapsulated class in Java.
Example:
public class Student{
//private data member
private String name;
//getter method for name
public String getName(){
return name;
}
//setter method for name
public void setName(String name){
this.name=name
} }

6. Polymorphism: Polymorphism in Java is a concept by which we can perform a single action in


different ways. Polymorphism is derived from 2 Greek words: poly and morphs. The word "poly"
means many and "morphs" means forms. So polymorphism means many forms.
There are two types of polymorphism in Java: compile-time polymorphism and runtime
polymorphism. We can perform polymorphism in java by method overloading and method
overriding.

Method Overloading: If a class has multiple methods having same name but different in parameters,
it is known as Method Overloading. If we have to perform only one operation, having same name of
the methods increases the readability of the program.
Example1:
class Adder{
static int add(int a,int b){return a+b;}
static int add(int a,int b,int c){return a+b+c;}
}
class TestOverloading1{
public static void main(String[] args){
System.out.println(Adder.add(11,11));
System.out.println(Adder.add(11,11,11));
}}
Example2:
class Adder{
static int add(int a, int b){return a+b;}
static double add(double a, double b){return a+b;}
}
class TestOverloading2{
public static void main(String[] args){
System.out.println(Adder.add(11,11));
System.out.println(Adder.add(12.3,12.6));

6
PPL Unit-4

}}

Method Overriding: If subclass (child class) has the same method as declared in the parent class, it is
known as method overriding in Java.
In other words, If a subclass provides the specific implementation of the method that has been
declared by one of its parent class, it is known as method overriding.
Example:
class Vehicle{
void run(){System.out.println("Vehicle is running");}
}
//Creating a child class
class Bike extends Vehicle{
public static void main(String args[]){
//creating an instance of child class
Bike obj = new Bike(); Output:
//calling the method with child class instance
obj.run();
}
}

Runtime Polymorphism: Runtime polymorphism or Dynamic Method Dispatch is a process in which


a call to an overridden method is resolved at runtime rather than compile-time.
Example:
class Bike{
void run(){System.out.println("running");}
}
class Splendor extends Bike{
void run(){System.out.println("running safely with 60km");}
public static void main(String args[]){
Bike b = new Splendor();//upcasting
b.run();
}
}

Compile Time Polymorphism: Compile-time polymorphism sometimes referred to as static


polymorphism or early binding, is the capacity of a programming language to decide which method
or function to use based on the quantity, kind, and sequence of inputs at compile-time. Method
overloading, which enables the coexistence of many methods with the same name but distinct
parameter lists within a class, enables Java to accomplish compile-time polymorphism.
Example:
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public static void main(String[] args) {
Calculator calc = new Calculator();
int sum1 = calc.add(5, 10);
System.out.println("Sum of 5 and 10 (integers): " + sum1);
double sum2 = calc.add(2.5, 3.7);
System.out.println("Sum of 2.5 and 3.7 (doubles): " + sum2); } }
7
PPL Unit-4

Fragmentation
Fragmentation is an unwanted problem in the operating system in which the processes are loaded
and unloaded from memory, and free memory space is fragmented. Processes can't be assigned to
memory blocks due to their small size, and the memory blocks stay unused.
Types of Fragmentation
1. Internal Fragmentation: When a process is allocated to a memory block, and if the process is
smaller than the amount of memory requested, a free space is created in the given memory
block. Due to this, the free space of the memory block is unused, which causes internal
fragmentation.
For Example: Assume that memory allocation in RAM is done using fixed partitioning (i.e., memory
blocks of fixed sizes). 2MB, 4MB, 4MB, and 8MB are the available sizes. The Operating System uses a
part of this RAM.

Let's suppose a process P1 with a size of 3MB arrives and is given a memory block of 4MB. As a
result, the 1MB of free space in this block is unused and cannot be used to allocate memory to
another process. It is known as internal fragmentation.
2. External Fragmentation: External fragmentation happens when a dynamic memory
allocation method allocates some memory but leaves a small amount of memory unusable.
The quantity of available memory is substantially reduced if there is too much external
fragmentation. There is enough memory space to complete a request, but it is not
contiguous. It's known as external fragmentation.
For Example:

Let's take the example of external fragmentation. In the above diagram, you can see that there is
sufficient space (50 KB) to run a process (05) (need 45KB), but the memory is not contiguous. You can
use compaction, paging, and segmentation to use the free space to execute a process.

8
PPL Unit-4

 Storage Allocation:
Storage management is a data storage technique which automatically moves data between high-cost
and low-cost storage media.
The different ways to allocate memory are:
1. Static storage allocation(fixed location, fixed size)
2. Stack storage allocation(variable location, fixed size)
3. Heap storage allocation(variable location, variable size)
1. Static storage allocation:
 In static allocation, names are bound to storage locations.
 If memory is created at compile time then the memory will be created in static area and only
once.
 Static allocation supports the dynamic data structure that means memory is created only at
compile time and deallocated after program completion.
 The drawback with static storage allocation is that the size and position of data objects
should be known at compile time.
 Another drawback is restriction of the recursion procedure.

Key points about static storage management:


i. Memory Allocation: Memory is allocated during compilation and is typically fixed in size. The
compiler determines the memory needed for variables based on their data types.
ii. Lifetime: Memory remains allocated for the entire duration of the program's execution, from
start to finish.
iii. Predictability: Since memory is allocated at compile-time, the program's memory usage is
known in advance. This can be advantageous for resource-constrained environments.
iv. Scope: Variables with static storage duration have a global or file scope, meaning they can be
accessed from different parts of the program.
v. Examples: Global variables in C or C++, static members in classes, and constants declared at
compile-time.

2. Stack Storage Allocation


 In static storage allocation, storage is organized as a stack.
 An activation record is pushed into the stack when activation begins and it is popped when
the activation end.
 Activation record contains the locals so that they are bound to fresh storage in each
activation record. The value of locals is deleted when the activation ends.
 It works on the basis of last-in-first-out (LIFO) and this allocation supports the recursion
process.
Key points about stack-based storage management:
i. Memory Allocation: Memory is allocated and deallocated in a last-in, first-out (LIFO) manner
as function calls and variable scopes are entered and exited.
ii. Lifetime: Variables allocated on the stack have a relatively short lifetime. They exist only
within the scope of the block (enclosed by curly braces) in which they are declared.
iii. Efficiency: Stack allocation and deallocation are typically faster than dynamic memory
allocation (e.g., heap allocation) because of the simple LIFO structure.
iv. Automatic Deallocation: Memory management is automatic; when a variable's scope ends,
its memory is automatically deallocated, reducing the risk of memory leaks.
v. Limitations: Stack-based memory is limited and suited for relatively small data structures.
Deeply nested function calls or large allocations can lead to stack overflow errors.
vi. Examples: Local variables in most programming languages, function call stacks, and
execution context storage.

9
PPL Unit-4

3. Heap Storage Allocation


 Heap allocation is the most flexible allocation scheme.
 Allocation and deallocation of memory can be done at any time and at any place depending
upon the user's requirement.
 Heap allocation is used to allocate memory to the variables dynamically and when the
variables are no more used then claim it back.
 Heap storage allocation supports the recursion process.
Example:
fact (int n)
{
if (n<=1)
return 1;
else
return (n * fact(n-1));
}
fact (6)

Fixed and Variable size heap storage management:


Fixed and variable size heap storage management are approaches used in memory management to
allocate and manage memory dynamically at runtime. These approaches play a crucial role in
enabling programs to efficiently allocate memory for data structures whose sizes may not be known
at compile-time. Let's explore these concepts:
 Fixed Size Heap Storage Management:
In fixed size heap storage management, memory is allocated and deallocated from a predefined set
of fixed-size blocks in the heap. Each block is of a uniform size, and the program requests these
blocks as needed. If a requested block is not available, the program may need to wait until one
becomes free.
Key points about fixed size heap storage management:
i. Memory Allocation: Memory is allocated in fixed-size blocks from the heap. These blocks are
typically of equal size, which may be chosen based on the anticipated usage patterns and
memory requirements of the program.
ii. Fragmentation: Over time, as blocks are allocated and deallocated, the heap can become
fragmented, meaning that small gaps of unused memory may accumulate between allocated
blocks. This can lead to inefficient use of memory.
iii. Allocation Efficiency: Fixed size heap storage can be efficient when the sizes of the data
structures being allocated are relatively uniform and well-suited to the block size.
iv. Predictability: The program's memory usage pattern is more predictable since it relies on a
fixed block size.
v. Examples: Memory allocators that use memory pools, slab allocators, and similar
techniques.

 Variable Size Heap Storage Management:


Variable size heap storage management allows memory to be allocated and deallocated in blocks of
varying sizes. This approach provides more flexibility in managing memory for data structures of
different sizes.
Key points about variable size heap storage management:
i. Memory Allocation: Memory is allocated in variable-sized blocks from the heap. This allows
more efficient use of memory since allocations can more closely match the actual size
requirements of data structures.

10
PPL Unit-4

ii. Fragmentation: Variable size heap storage can help reduce fragmentation compared to fixed
size heaps, as memory can be allocated in sizes that best fit the data structures.
iii. Allocation Overhead: Managing variable-sized blocks can introduce some overhead, as the
allocator needs to keep track of available memory blocks and manage their sizes.
iv. Examples: Common memory allocation functions in languages like C and C++ (e.g., malloc,
calloc, realloc), as well as more advanced memory management techniques used in modern
programming languages.

 Garbage Collection
Garbage Collection is process of reclaiming the runtime unused memory automatically. In other
words, it is a way to destroy the unused objects.
To do so, we were using free() function in C language and delete() in C++. But, in java it is performed
automatically. So, java provides better memory management.
It helps prevent memory leaks, where memory is allocated but not properly deallocated, leading to
inefficient memory usage and potential program instability. Garbage collection is particularly
important in languages that offer dynamic memory allocation.
 Advantage of Garbage Collection
 It makes memory efficient because garbage collector removes the unreferenced objects
from heap memory.
 It is automatically done by the garbage collector(a part of JVM) so we don't need to make
extra efforts.

 How Garbage Collection Works:


1. Reachability Analysis: Garbage collection starts by identifying objects that are still reachable
and in use by the program. This is typically done by tracing references from well-known roots
(e.g., global variables, local variables, and active threads) to other objects in memory.
2. Mark Phase: During the mark phase, reachable objects are marked or flagged to indicate
that they are still in use. Unreachable objects remain unmarked.
3. Sweep and Deallocate: After marking, the garbage collector sweeps through the memory to
identify unmarked (unreachable) objects. These unmarked objects are no longer needed and
can be deallocated, freeing up memory.
4. Compact (Optional): In some garbage collection algorithms, a compaction phase may follow.
This phase rearranges the remaining live objects in memory to reduce fragmentation and
create larger contiguous blocks of free memory.

 Types of Garbage Collector in java


1. Serial Garbage Collector: Serial Garbage collector is well-
matched for single-threaded environments. It uses the only
thread for garbage collection. It works by holding all the
threads of an application. It means that threads of the
application freeze by the serial garbage collector during the
garbage collection process and the process is known as stop
the world event. Avoid the use of serial GC in the server
environment. We can use it for simple programs. If you want
to use the serial garbage collector, execute the -
XX:+UseSerialGC JVM argument to activate it.

2. Parallel Garbage Collector: Parallel Garbage Collector is the default


GC used by the JVM. The working of the parallel garbage collector is
the same as the serial garbage collector. The only difference
between serial and parallel garbage collector is that serial garbage
collector uses a single thread for garbage collection process while
the parallel garbage collector uses multiple threads for the garbage

11
PPL Unit-4

collection. Parallel GC can use multiple CPUs to speed up the application throughput. So, it is also
known as throughput collector. It is used if we want to execute a long process (like batch
processing) and where long pauses are acceptable. If you want to use the parallel garbage
collector, execute the -XX:+UseParallelGC JVM argument to activate it.

3. Concurrent Mark and Sweep (CMS) Garbage Collector


CMS uses multiple threads that scan the heap and during the
scanning, it marks the instances for eviction, after scanning, it
sweeps the marked instances. It does not freeze the
application's threads during the garbage collection. GC threads
concurrently execute with the application's threads. For this
reason, it uses more CPU in comparison to other GC. It is also
known as the concurrent low pause collector. It also freezes all
the threads of the application only if it satisfies the following
two scenarios:
 while marking the referenced objects in the tenured
generation region.
 if any change is made to the heap memory in parallel
during the garbage collection process.
We can use multiple CPUs for better application throughput. We
should use a CMS garbage collector if we have more CPUs for
use. Hence, it has an advantage over the parallel garbage
collector. If you want to use a CMS garbage collector, execute the -XX:+USeParNewGC JVM argument
to activate it. We can also set the number of GC threads by using the -XX:ParallelCMSThreads=<n>
JVM argument.
Garbage First (G1) Garbage Collector: The G1 garbage
collector is used if we have a large (more than 4GB) memory
(heap space). It divides the heap into equal-sized (usually
1MB to 32MB) chunks, prioritizes them, and then performs
the parallel garbage collection on that chunks based on the
priority.
The Eden, survivors, and old areas use this equal-sized region
for the memory allocation of the objects. Apart from these
memory regions, there are two more types of regions
presented in the G1 GC:
 Humongous: It is used if the object sized is large.
 Available: It represents the unoccupied space.

G1 GC shows a concurrent global marking phase to determine the live and dead objects throughout
the heap. After the completion of the mark phase, G1 collects the information of regions that
contains the most garbage objects. After that these regions are swept first. If you want to use the G1
garbage collector, execute the -XX:+UseG1GC JVM argument to activate it.
Stop the World Event
It is a situation when the garbage collector performs the garbage collection (GC) and stops all the
application's threads until the GC process is not completed. The process is known as Stop the World
(STW) events.

12

You might also like